using Fengling.Console.Datas;
using Fengling.Console.Models.Entities;
using Microsoft.EntityFrameworkCore;

namespace Fengling.Console.Repositories;

public class UserRepository : IUserRepository
{
    private readonly ApplicationDbContext _context;

    public UserRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<ApplicationUser?> GetByIdAsync(long id)
    {
        return await _context.Users.FindAsync(id);
    }

    public async Task<ApplicationUser?> GetByUserNameAsync(string userName)
    {
        return await _context.Users.FirstOrDefaultAsync(u => u.UserName == userName);
    }

    public async Task<IEnumerable<ApplicationUser>> GetAllAsync()
    {
        return await _context.Users.ToListAsync();
    }

    public async Task<IEnumerable<ApplicationUser>> GetPagedAsync(int page, int pageSize, string? userName = null,
        string? email = null, string? tenantCode = null)
    {
        var query = _context.Users.AsQueryable();

        if (!string.IsNullOrEmpty(userName))
        {
            query = query.Where(u => u.UserName != null && u.UserName.Contains(userName));
        }

        if (!string.IsNullOrEmpty(email))
        {
            query = query.Where(u => u.Email != null && u.Email.Contains(email));
        }

        if (!string.IsNullOrEmpty(tenantCode))
        {
            query = query.Where(u => u.TenantId.ToString().Contains(tenantCode));
        }

        return await query
            .OrderByDescending(u => u.CreatedTime)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    public async Task<int> CountAsync(string? userName = null, string? email = null, string? tenantCode = null)
    {
        var query = _context.Users.AsQueryable();

        if (!string.IsNullOrEmpty(userName))
        {
            query = query.Where(u => u.UserName != null && u.UserName.Contains(userName));
        }

        if (!string.IsNullOrEmpty(email))
        {
            query = query.Where(u => u.Email != null && u.Email.Contains(email));
        }

        if (!string.IsNullOrEmpty(tenantCode))
        {
            query = query.Where(u => u.TenantId.ToString().Contains(tenantCode));
        }

        return await query.CountAsync();
    }

    public async Task AddAsync(ApplicationUser user)
    {
        _context.Users.Add(user);
        await _context.SaveChangesAsync();
    }

    public async Task UpdateAsync(ApplicationUser user)
    {
        _context.Users.Update(user);
        await _context.SaveChangesAsync();
    }

    public async Task DeleteAsync(ApplicationUser user)
    {
        _context.Users.Remove(user);
        await _context.SaveChangesAsync();
    }
}
