using CMSMicroservice.Application.Common.Exceptions;
using CMSMicroservice.Application.Common.Interfaces;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.UserOrderCQ.Queries.CalculateOrderPV;

public class CalculateOrderPVQueryHandler : IRequestHandler<CalculateOrderPVQuery, CalculateOrderPVResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<CalculateOrderPVQueryHandler> _logger;

    // نسبت PV به قیمت بر اساس مثال‌های بیزینسی:
    // محصول ۱: قیمت 100,000 → PV = 50
    // محصول ۲: قیمت 200,000 → PV = 100
    // یعنی: PV = Price / 2000
    private const decimal PvPerRial = 1m / 2000m;

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

    public async Task<CalculateOrderPVResponseDto> Handle(CalculateOrderPVQuery request, CancellationToken cancellationToken)
    {
        var order = await _context.UserOrders
            .Include(o => o.FactorDetails)
            .ThenInclude(fd => fd.Product)
            .FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);

        if (order == null)
        {
            throw new NotFoundException(nameof(order), request.OrderId);
        }

        var productPVs = new List<ProductPVDto>();
        decimal totalPV = 0;

        foreach (var detail in order.FactorDetails)
        {
            if (detail.Product == null)
            {
                continue;
            }

            var unitPrice = detail.Product.Price;
            var unitPV = Math.Round(unitPrice * PvPerRial, 2, MidpointRounding.AwayFromZero);
            var itemTotalPV = unitPV * detail.Count;

            productPVs.Add(new ProductPVDto
            {
                ProductId = detail.ProductId,
                ProductTitle = detail.Product.Title,
                Quantity = detail.Count,
                UnitPV = unitPV,
                TotalPV = itemTotalPV,
                UnitPrice = unitPrice
            });

            totalPV += itemTotalPV;
        }

        var response = new CalculateOrderPVResponseDto
        {
            TotalPV = totalPV,
            ProductPVs = productPVs,
            // فعلاً مبلغ قابل پرداخت همان Amount است؛ در آینده می‌توان تخفیف را هم اعمال کرد
            PayableAmount = order.Amount
        };

        _logger.LogInformation(
            "Calculated PV for order {OrderId}: {TotalPV}",
            request.OrderId,
            totalPV);

        return response;
    }
}
