namespace CMSMicroservice.Application.CommissionCQ.Queries.GetUserWeeklyBalances;

public class GetUserWeeklyBalancesQueryHandler : IRequestHandler<GetUserWeeklyBalancesQuery, GetUserWeeklyBalancesResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IWeekDefinitionRepository _weekDefinitionRepository;

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

    public async Task<GetUserWeeklyBalancesResponseDto> Handle(GetUserWeeklyBalancesQuery request, CancellationToken cancellationToken)
    {
        var pageSize   = request.PaginationState?.PageSize   > 0 ? request.PaginationState.PageSize   : PaginationDefaults.PageSize;
        var pageNumber = request.PaginationState?.PageNumber > 0 ? request.PaginationState.PageNumber : PaginationDefaults.PageNumber;

        // تشخیص جهت مرتب‌سازی از SortBy (پیش‌فرض: نزولی)
        var sortBy         = request.SortBy ?? "-WeekDefinitionId";
        int sortDescending = sortBy.StartsWith("-") ? 1 : 0;

        long? userId          = request.UserId.HasValue && request.UserId.Value > 0 ? request.UserId : null;
        long? weekDefinitionId = request.WeekDefinitionId.HasValue ? request.WeekDefinitionId : null;
        long? packageId       = request.PackageId.HasValue && request.PackageId.Value > 0 ? request.PackageId : null;
        int   onlyActive      = request.OnlyActive.HasValue && request.OnlyActive.Value ? 1 : 0;

        var rows = await _context.Database
            .SqlQuery<GetUserWeeklyBalancesResponseModel>(
                $"""
                EXEC [CMS].[sp_GetUserWeeklyBalances]
                    @UserId           = {userId},
                    @WeekDefinitionId = {weekDefinitionId},
                    @PackageId        = {packageId},
                    @OnlyActive       = {onlyActive},
                    @SortDescending   = {sortDescending},
                    @PageNumber       = {pageNumber},
                    @PageSize         = {pageSize}
                """)
            .ToListAsync(cancellationToken);

        var totalCount     = rows.Count > 0 ? rows[0].TotalCount : 0;
        var totalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);

        var meta = new MetaData
        {
            CurrentPage  = pageNumber,
            PageSize     = pageSize,
            TotalCount   = totalCount,
            TotalPage    = totalPageCount,
            HasNext      = pageNumber < totalPageCount,
            HasPrevious  = pageNumber > 1
        };

        return new GetUserWeeklyBalancesResponseDto
        {
            MetaData = meta,
            Models   = rows
        };
    }
}
