using Microsoft.EntityFrameworkCore;
using MembershipService.Domain.AggregatesModel.LevelAggregate;
using MembershipService.Domain.SeedWork;

namespace MembershipService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for LevelDefinition aggregate.
/// VI: Repository implementation cho LevelDefinition aggregate.
/// </summary>
public class LevelDefinitionRepository : ILevelDefinitionRepository
{
    private readonly MembershipServiceContext _context;

    public LevelDefinitionRepository(MembershipServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public IUnitOfWork UnitOfWork => _context;

    /// <summary>
    /// EN: Get level definition by ID.
    /// VI: Lấy level definition theo ID.
    /// </summary>
    public async Task<LevelDefinition?> GetAsync(Guid id)
    {
        return await _context.LevelDefinitions
            .FirstOrDefaultAsync(l => l.Id == id);
    }

    /// <summary>
    /// EN: Get level definition by level number.
    /// VI: Lấy level definition theo số thứ tự level.
    /// </summary>
    public async Task<LevelDefinition?> GetByLevelNumberAsync(int levelNumber)
    {
        return await _context.LevelDefinitions
            .FirstOrDefaultAsync(l => EF.Property<int>(l, "_levelNumber") == levelNumber);
    }

    /// <summary>
    /// EN: Get level definition with benefits.
    /// VI: Lấy level definition kèm benefits.
    /// </summary>
    public async Task<LevelDefinition?> GetWithBenefitsAsync(Guid id)
    {
        return await _context.LevelDefinitions
            .Include(l => l.Benefits)
            .FirstOrDefaultAsync(l => l.Id == id);
    }

    /// <summary>
    /// EN: Get all active level definitions ordered by level number.
    /// VI: Lấy tất cả level definitions đang active, sắp xếp theo số thứ tự.
    /// </summary>
    public async Task<IReadOnlyList<LevelDefinition>> GetAllActiveAsync()
    {
        return await _context.LevelDefinitions
            .Where(l => EF.Property<bool>(l, "_isActive"))
            .OrderBy(l => EF.Property<int>(l, "_levelNumber"))
            .ToListAsync();
    }

    /// <summary>
    /// EN: Get all level definitions (including inactive).
    /// VI: Lấy tất cả level definitions (bao gồm cả inactive).
    /// </summary>
    public async Task<IReadOnlyList<LevelDefinition>> GetAllAsync()
    {
        return await _context.LevelDefinitions
            .OrderBy(l => EF.Property<int>(l, "_levelNumber"))
            .ToListAsync();
    }

    /// <summary>
    /// EN: Check if level number already exists.
    /// VI: Kiểm tra xem số thứ tự level đã tồn tại chưa.
    /// </summary>
    public async Task<bool> ExistsByLevelNumberAsync(int levelNumber)
    {
        return await _context.LevelDefinitions
            .AnyAsync(l => EF.Property<int>(l, "_levelNumber") == levelNumber);
    }

    /// <summary>
    /// EN: Add new level definition.
    /// VI: Thêm level definition mới.
    /// </summary>
    public LevelDefinition Add(LevelDefinition levelDefinition)
    {
        return _context.LevelDefinitions.Add(levelDefinition).Entity;
    }

    /// <summary>
    /// EN: Update level definition.
    /// VI: Cập nhật level definition.
    /// </summary>
    public void Update(LevelDefinition levelDefinition)
    {
        _context.Entry(levelDefinition).State = EntityState.Modified;
    }
}
