using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.ManualPaymentCQ.Queries.GetAllManualPayments;

public class GetAllManualPaymentsQueryHandler 
    : IRequestHandler<GetAllManualPaymentsQuery, GetAllManualPaymentsResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<GetAllManualPaymentsQueryHandler> _logger;

    public GetAllManualPaymentsQueryHandler(
        IApplicationDbContext context,
        ILogger<GetAllManualPaymentsQueryHandler> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<GetAllManualPaymentsResponseDto> Handle(
        GetAllManualPaymentsQuery request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Getting manual payments. Page: {Page}, PageSize: {PageSize}",
            request.PageNumber,
            request.PageSize
        );

        // ساخت Query با فیلترها
        var query = _context.ManualPayments
            .Include(m => m.User)
            .AsQueryable();

        // فیلتر UserId
        if (request.UserId.HasValue)
        {
            query = query.Where(m => m.UserId == request.UserId.Value);
        }

        // فیلتر Status
        if (request.Status.HasValue)
        {
            query = query.Where(m => m.Status == request.Status.Value);
        }

        // فیلتر Type
        if (request.Type.HasValue)
        {
            query = query.Where(m => m.Type == request.Type.Value);
        }

        // فیلتر RequestedBy
        if (request.RequestedBy.HasValue)
        {
            query = query.Where(m => m.RequestedBy == request.RequestedBy.Value);
        }

        // شمارش کل
        var totalCount = await query.CountAsync(cancellationToken);

        // مرتب‌سازی
        query = request.OrderByDescending
            ? query.OrderByDescending(m => m.Created)
            : query.OrderBy(m => m.Created);

        // Pagination
        var skip = (request.PageNumber - 1) * request.PageSize;
        var data = await query
            .Skip(skip)
            .Take(request.PageSize)
            .Select(m => new ManualPaymentDto
            {
                Id = m.Id,
                UserId = m.UserId,
                UserFullName = m.User.FirstName + " " + m.User.LastName,
                UserMobile = m.User.Mobile ?? "",
                Amount = m.Amount,
                Type = m.Type,
                TypeDisplay = m.Type.ToString(),
                Description = m.Description,
                ReferenceNumber = m.ReferenceNumber,
                Status = m.Status,
                StatusDisplay = m.Status.ToString(),
                RequestedBy = m.RequestedBy,
                RequestedByName = "", // باید از جدول User گرفته شود
                ApprovedBy = m.ApprovedBy,
                ApprovedByName = null,
                ApprovedAt = m.ApprovedAt,
                RejectionReason = m.RejectionReason,
                TransactionId = m.TransactionId,
                Created = m.Created
            })
            .ToListAsync(cancellationToken);

        var metaData = new MetaData
        {
            TotalCount = totalCount,
            PageSize = request.PageSize,
            CurrentPage = request.PageNumber,
            TotalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasNext = request.PageNumber < (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasPrevious = request.PageNumber > 1
        };

        _logger.LogInformation(
            "Retrieved {Count} manual payments. Total: {Total}",
            data.Count,
            totalCount
        );

        return new GetAllManualPaymentsResponseDto
        {
            MetaData = metaData,
            Models = data
        };
    }
}
