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

namespace CMSMicroservice.Application.DiscountShopCQ.Queries.GetAllDiscountOrders;

public class GetAllDiscountOrdersQueryHandler : IRequestHandler<GetAllDiscountOrdersQuery, GetAllDiscountOrdersResponseDto>
{
    private readonly IApplicationDbContext _context;

    public GetAllDiscountOrdersQueryHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<GetAllDiscountOrdersResponseDto> Handle(GetAllDiscountOrdersQuery request, CancellationToken cancellationToken)
    {
        var query = _context.DiscountOrders
            .Include(o => o.User)
            .Include(o => o.UserAddress)
            .AsQueryable();

        // فیلتر بر اساس شناسه کاربر
        if (request.UserId.HasValue)
        {
            query = query.Where(o => o.UserId == request.UserId.Value);
        }

        // فیلتر بر اساس وضعیت پرداخت
        if (request.PaymentStatus.HasValue)
        {
            query = query.Where(o => o.PaymentStatus == request.PaymentStatus.Value);
        }

        // فیلتر بر اساس وضعیت ارسال
        if (request.DeliveryStatus.HasValue)
        {
            query = query.Where(o => o.DeliveryStatus == request.DeliveryStatus.Value);
        }

        // جستجو بر اساس موبایل کاربر
        if (!string.IsNullOrWhiteSpace(request.UserMobile))
        {
            query = query.Where(o => o.User.Mobile.Contains(request.UserMobile));
        }

        // جستجو بر اساس کد رهگیری
        if (!string.IsNullOrWhiteSpace(request.TrackingCode))
        {
            query = query.Where(o => o.TrackingCode != null && o.TrackingCode.Contains(request.TrackingCode));
        }

        // فیلتر از تاریخ
        if (request.FromDate.HasValue)
        {
            query = query.Where(o => o.Created >= request.FromDate.Value);
        }

        // فیلتر تا تاریخ
        if (request.ToDate.HasValue)
        {
            query = query.Where(o => o.Created <= request.ToDate.Value);
        }

        // فیلتر حداقل مبلغ
        if (request.MinAmount.HasValue)
        {
            query = query.Where(o => o.TotalAmount >= request.MinAmount.Value);
        }

        // فیلتر حداکثر مبلغ
        if (request.MaxAmount.HasValue)
        {
            query = query.Where(o => o.TotalAmount <= request.MaxAmount.Value);
        }

        var totalCount = await query.CountAsync(cancellationToken);

        // Apply pagination
        var pagination = request.PaginationQuery ?? new PaginationState { PageNumber = 1, PageSize = 20 };

        var rows = await query
            .OrderByDescending(o => o.Created)
            .Skip((pagination.PageNumber - 1) * pagination.PageSize)
            .Take(pagination.PageSize)
            .Select(o => new
            {
                o.Id,
                o.UserId,
                FirstName = o.User.FirstName,
                LastName = o.User.LastName,
                Mobile = o.User.Mobile,
                o.TotalAmount,
                o.DiscountBalanceUsed,
                o.GatewayAmountPaid,
                o.VatAmount,
                o.PaymentStatus,
                o.PaymentDate,
                o.DeliveryStatus,
                ShippingAddress = o.UserAddress.Address,
                ReceiverName = o.UserAddress.Title,
                o.TrackingCode,
                AdminNote = o.DeliveryDescription,
                o.Created,
                o.LastModified,
                ItemsCount = o.OrderDetails.Count
            })
            .ToListAsync(cancellationToken);

        var orders = rows.Select(o => new AdminOrderDto
        {
            Id = o.Id,
            UserId = o.UserId,
            UserFullName = UserDisplayName.From(o.FirstName, o.LastName, o.Mobile, o.UserId),
            UserMobile = o.Mobile,
            TotalAmount = o.TotalAmount,
            DiscountBalanceUsed = o.DiscountBalanceUsed,
            GatewayAmountPaid = o.GatewayAmountPaid,
            VatAmount = o.VatAmount,
            PaymentStatus = o.PaymentStatus,
            PaymentDate = o.PaymentDate,
            DeliveryStatus = o.DeliveryStatus,
            DeliveryDate = null,
            ShippingAddress = o.ShippingAddress,
            ReceiverName = o.ReceiverName,
            ReceiverMobile = o.Mobile,
            TrackingCode = o.TrackingCode,
            AdminNote = o.AdminNote,
            Created = o.Created,
            LastModified = o.LastModified,
            ItemsCount = o.ItemsCount
        }).ToList();

        return new GetAllDiscountOrdersResponseDto
        {
            MetaData = new MetaData
            {
                TotalCount = totalCount,
                PageSize = pagination.PageSize,
                CurrentPage = pagination.PageNumber,
                TotalPage = (int)Math.Ceiling(totalCount / (double)pagination.PageSize)
            },
            Models = orders
        };
    }
}
