namespace CMSMicroservice.Application.CommissionCQ.Queries.GetUserCommissionPayouts;

public class GetUserCommissionPayoutsQueryHandler : IRequestHandler<GetUserCommissionPayoutsQuery, GetUserCommissionPayoutsResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IWeekDefinitionRepository _weekDefinitionRepository;

    public GetUserCommissionPayoutsQueryHandler(
        IApplicationDbContext context,
        IWeekDefinitionRepository weekDefinitionRepository)
    {
        _context = context;
        _weekDefinitionRepository = weekDefinitionRepository;
    }

    public async Task<GetUserCommissionPayoutsResponseDto> Handle(GetUserCommissionPayoutsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.UserCommissionPayouts
            .Include(x => x.WeekDefinition)
            .Include(x => x.User)
            .Include(x => x.Package)
            .AsNoTracking()
            .AsQueryable();

        // UserId > 0 → filter by that user
        // UserId == 0 or null → show ALL users (admin mode)
        // Customer endpoints resolve UserId from JWT before calling this handler
        long? userId = request.UserId;

        if (userId.HasValue && userId.Value > 0)
        {
            query = query.Where(x => x.UserId == userId.Value);
        }

        if (request.Status.HasValue)
        {
            query = query.Where(x => x.Status == request.Status.Value);
        }

        if (request.WeekDefinitionId!=null)
        {
            query = query.Where(x => x.WeekDefinitionId == request.WeekDefinitionId);
        }

        // فیلتر بر اساس پکیج
        if (request.PackageId.HasValue && request.PackageId.Value > 0)
        {
            query = query.Where(x => x.PackageId == request.PackageId.Value);
        }

        query = query.ApplyOrder(sortBy: request.SortBy ?? "Created");

        var meta = await query.GetMetaData(request.PaginationState, cancellationToken);

        var models = await query
            .PaginatedListAsync(paginationState: request.PaginationState)
            .Select(x => new GetUserCommissionPayoutsResponseModel
            {
                Id = x.Id,
                UserId = x.UserId,
                FirstName = x.User.FirstName,
                LastName = x.User.LastName,
                WeekDefinitionId = x.WeekDefinitionId,
                WeekDisplayName = x.WeekDefinition != null ? x.WeekDefinition.DisplayName : "",
                WeeklyPoolId = x.WeeklyPoolId,
                BalancesEarned = x.BalancesEarned,
                ValuePerBalance = x.ValuePerBalance,
                TotalAmount = x.TotalAmount,
                Status = x.Status,
                PaidAt = x.PaidAt,
                WithdrawalMethod = x.WithdrawalMethod,
                IbanNumber = x.IbanNumber,
                WithdrawnAt = x.WithdrawnAt,
                Created = x.Created,
                PackageId = x.PackageId,
                PackageTitle = x.Package != null ? x.Package.Title : ""
            })
            .ToListAsync(cancellationToken);

        // // Populate WeekDisplayName from cache
        // foreach (var model in models)
        // {
        //     model.WeekDisplayName = _weekDefinitionRepository.GetDisplayNameByGregorianWeekNumber(model.WeekNumber);
        // }

        return new GetUserCommissionPayoutsResponseDto
        {
            MetaData = meta,
            Models = models
        };
    }
}
