using Microsoft.EntityFrameworkCore;
using Modules.User.Database.Database;
using System.Linq.Expressions;

namespace Modules.User.Database.Repositories;

public class UserRepository1(UserDbContext context)
{
    private readonly UserDbContext _context = context;

    internal async Task<Guid> AddAsync(Database.Entities.User user)
    {
        _context.Users.Add(user);
        await _context.SaveChangesAsync();
        return user.Id;
    }

    internal async Task<bool> DeleteAsync(Guid userId)
    {
        var user = await _context.Users
            .Include(user => user.Account)
            .FirstOrDefaultAsync(q => q.Id == userId);
        if (user != null)
        {
            user.Deleted = true;
            user.Account.Deleted = true;
            await _context.SaveChangesAsync();
            return true;
        }
        else return false;
    }


    private IQueryable<Database.Entities.User> FilteredUserQuery(bool? hasAvatar, string? nickName,
        DateTimeOffset? lastOnlineFrom = null,  DateTimeOffset? lastOnlineTo = null, bool? isBanned = null)
    {
        var query = UserQuery();
        if (hasAvatar.HasValue)
        {
            query = query.Where(q => !string.IsNullOrWhiteSpace(q.AvatarId));
        }

        if (!string.IsNullOrWhiteSpace(nickName))
        {
            query = query.Where(q => q.NickName.ToLower().StartsWith(nickName.ToLower()));
        }

        if (lastOnlineFrom.HasValue)
        {
            query = query.Where(q => q.Account.Sessions.Any(x => x.LastUpdate >= lastOnlineFrom));
        }
        if (lastOnlineTo.HasValue)
        {
            query = query.Where(q => q.Account.Sessions.Any(x => x.LastUpdate <= lastOnlineTo));
        }

        // if (isBanned.HasValue)
        // {
        //     // query = query.Where(q => q.Deleted.)
        // }
        //check banlist
        
        return query;
    }
    
    internal async Task<int> GetFilteredCountAsync(bool? hasAvatar, string? nickName,
        DateTimeOffset? lastOnlineFrom = null,  DateTimeOffset? lastOnlineTo = null, bool? isBanned = null)
    {
        return await FilteredUserQuery(hasAvatar, nickName, lastOnlineFrom, lastOnlineTo,isBanned).CountAsync();
    }

    internal async Task<IEnumerable<Database.Entities.User>> GetWhereAsync(bool? hasAvatar, string? nickName,
        DateTimeOffset? lastOnlineFrom = null,  DateTimeOffset? lastOnlineTo = null,
        bool? isBanned = null, int skip = 0, int take = 10)
    {
        return await FilteredUserQuery(hasAvatar, nickName, lastOnlineFrom, lastOnlineTo,isBanned)
            .OrderBy(q => q.NickName).Skip(skip).Take(take).ToListAsync();
    }

    internal async Task<Database.Entities.User?> GetFirstOrDefaultWhereAsync(Expression<Func<Database.Entities.User, bool>> predicate) =>
        await UserQuery().FirstOrDefaultAsync(predicate);

    internal async Task<Database.Entities.User> GetFirstWhereAsync(Expression<Func<Database.Entities.User, bool>> predicate) =>
        await UserQuery().FirstAsync(predicate);

    internal async Task UpdateUserAsync() => await _context.SaveChangesAsync();

    private IQueryable<Database.Entities.User> UserQuery() => _context.Users
        .Include(q => q.Account).ThenInclude(q => q.Sessions)
        .Include(q => q.RegionalSettings).AsQueryable();
}