// EN: Repository implementation for attendance records.
// VI: Implementation repository cho ban ghi cham cong.

using MerchantService.Domain.AggregatesModel.AttendanceAggregate;
using MerchantService.Domain.SeedWork;
using Microsoft.EntityFrameworkCore;

namespace MerchantService.Infrastructure.Repositories;

public class AttendanceRepository : IAttendanceRepository
{
    private readonly MerchantServiceContext _context;
    public IUnitOfWork UnitOfWork => _context;

    public AttendanceRepository(MerchantServiceContext context) => _context = context;

    public async Task<AttendanceRecord?> GetByIdAsync(Guid id, CancellationToken ct = default)
        => await _context.AttendanceRecords.FirstOrDefaultAsync(a => a.Id == id, ct);

    public async Task<AttendanceRecord?> GetTodayRecordAsync(Guid staffId, CancellationToken ct = default)
    {
        var today = DateTime.UtcNow.Date;
        return await _context.AttendanceRecords
            .FirstOrDefaultAsync(a => a.StaffId == staffId && a.Date == today, ct);
    }

    public async Task<List<AttendanceRecord>> GetByStaffAndMonthAsync(Guid staffId, int month, int year, CancellationToken ct = default)
    {
        var startDate = new DateTime(year, month, 1, 0, 0, 0, DateTimeKind.Utc);
        var endDate = startDate.AddMonths(1);
        return await _context.AttendanceRecords
            .Where(a => a.StaffId == staffId && a.Date >= startDate && a.Date < endDate)
            .OrderByDescending(a => a.Date)
            .ToListAsync(ct);
    }

    public async Task<List<AttendanceRecord>> GetByShopAndMonthAsync(Guid shopId, int month, int year, CancellationToken ct = default)
    {
        var startDate = new DateTime(year, month, 1, 0, 0, 0, DateTimeKind.Utc);
        var endDate = startDate.AddMonths(1);
        return await _context.AttendanceRecords
            .Where(a => a.ShopId == shopId && a.Date >= startDate && a.Date < endDate)
            .OrderByDescending(a => a.Date)
            .ToListAsync(ct);
    }

    public AttendanceRecord Add(AttendanceRecord record) => _context.AttendanceRecords.Add(record).Entity;
    public void Update(AttendanceRecord record) => _context.Entry(record).State = EntityState.Modified;
}
