using CMSMicroservice.Domain.Enums;
using CMSMicroservice.Domain.Events;
using CMSMicroservice.Domain.Entities.Order;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.UserOrderCQ.Commands.SubmitShopBuyOrder;

public class
    SubmitShopBuyOrderCommandHandler : IRequestHandler<SubmitShopBuyOrderCommand, SubmitShopBuyOrderResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<SubmitShopBuyOrderCommandHandler> _logger;

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

    public async Task<SubmitShopBuyOrderResponseDto> Handle(SubmitShopBuyOrderCommand request,
        CancellationToken cancellationToken)
    {
        var user = await _context.Users
            .Include(i => i.UserAddresses)
            .Include(i => i.UserWallets)
            .ThenInclude(i => i.UserWalletChangeLogs)
            .Include(i => i.UserCarts)
            .ThenInclude(i => i.Product)
            .FirstOrDefaultAsync(w => w.Id == request.UserId, cancellationToken: cancellationToken);
        if (user.UserCarts.Count == 0)
            throw new NotFoundException("UserCart", request.UserId);

        if (user.UserCarts.Sum(s => s.Count * s.Product.Price) != request.TotalAmount)
            throw new Exception("مبلغ سفارش با مجموع سبد خرید مطابقت ندارد.");


        var userWallet = user.UserWallets.FirstOrDefault();
        if (userWallet == null)
            throw new Exception("کیف پول کاربر یافت نشد.");
        
        if (userWallet.Balance<=0 || userWallet.Balance<request.TotalAmount)
            throw new Exception("موجودی کیف پول کاربر برای انجام این تراکنش کافی نیست.");
        
        var newTransaction = new Transaction()
        {
            Amount = request.TotalAmount,
            Description = "خرید از فروشگاه",
            PaymentStatus = PaymentStatus.Success,
            PaymentDate = DateTime.Now,
            Type = TransactionType.Buy,
            RefId = "localwallet-" + Guid.NewGuid().ToString()
        };
        await _context.Transactions.AddAsync(newTransaction, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);
        
        var newWalletLog = new UserWalletChangeLog()
        {
            CurrentBalance = userWallet.Balance,
            CurrentNetworkBalance = userWallet.NetworkBalance,
            WalletId = userWallet.Id,
            ChangeValue = -1*request.TotalAmount,
            IsIncrease = false,
            RefrenceId = newTransaction.Id,
        };
        userWallet.Balance -= request.TotalAmount;
        
        await _context.UserWalletChangeLogs.AddAsync(newWalletLog, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);

        var newOrder = new UserOrder()
        {
            Amount = request.TotalAmount,
            PaymentStatus = PaymentStatus.Success,
            PaymentMethod = PaymentMethod.Wallet,
            PaymentDate = DateTime.Now,
            UserId = request.UserId,
            UserAddressId = user.UserAddresses.First(f => f.IsDefault).Id,
            TransactionId = newTransaction.Id,
            // سفارش فروشگاهی فیزیکی است، پس در ابتدا در انتظار ارسال است
            DeliveryStatus = DeliveryStatus.Pending
        };
        await _context.UserOrders.AddAsync(newOrder, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);
        
        // محاسبه و ثبت VAT (اگر فعال باشد)
        var vatCreated = await CalculateAndSaveVAT(newOrder.Id, request.TotalAmount, cancellationToken);
        if (vatCreated)
        {
            newOrder.HasVAT = true;
            await _context.SaveChangesAsync(cancellationToken);
        }
        
        var factorDetailsList = user.UserCarts.Select(s => new FactorDetails()
        {
            ProductId = s.ProductId,
            Count = s.Count,
            UnitPrice = s.Product.Price,
            OrderId = newOrder.Id
        });
        await _context.FactorDetails.AddRangeAsync(factorDetailsList, cancellationToken);
        user.UserCarts.Clear();
        await _context.SaveChangesAsync(cancellationToken);
        var finalResult = new SubmitShopBuyOrderResponseDto()
        {
            Id = newOrder.Id,
  
        };
        return finalResult;
    }

    private async Task<bool> CalculateAndSaveVAT(long orderId, long orderAmount, CancellationToken cancellationToken)
    {
        try
        {
            // بررسی فعال بودن VAT
            var vatEnabledConfig = await _context.SystemConfigurations
                .FirstOrDefaultAsync(x => x.Scope == ConfigurationScope.VAT && x.Key == "IsEnabled", cancellationToken);

            if (vatEnabledConfig == null || !bool.TryParse(vatEnabledConfig.Value, out var isEnabled) || !isEnabled)
            {
                _logger.LogInformation("VAT is disabled. Skipping VAT calculation for order {OrderId}", orderId);
                return false;
            }

            // دریافت نرخ VAT
            var vatRateConfig = await _context.SystemConfigurations
                .FirstOrDefaultAsync(x => x.Scope == ConfigurationScope.VAT && x.Key == "Rate", cancellationToken);

            if (vatRateConfig == null || !decimal.TryParse(vatRateConfig.Value, out var vatRate))
            {
                _logger.LogWarning("VAT Rate configuration not found or invalid. Using default 0.09");
                vatRate = 0.09m;
            }

            // محاسبه مالیات
            var vatAmount = (long)(orderAmount * vatRate);
            var totalAmount = orderAmount + vatAmount;

            // ثبت VAT
            var orderVAT = new OrderVAT
            {
                OrderId = orderId,
                VATRate = vatRate,
                BaseAmount = orderAmount,
                VATAmount = vatAmount,
                TotalAmount = totalAmount,
                IsPaid = true,
                PaidAt = DateTime.UtcNow
            };

            await _context.OrderVATs.AddAsync(orderVAT, cancellationToken);
            await _context.SaveChangesAsync(cancellationToken);

            _logger.LogInformation(
                "VAT calculated and saved for order {OrderId}. Rate: {Rate}%, Base: {Base}, VAT: {VAT}, Total: {Total}",
                orderId,
                vatRate * 100,
                orderAmount,
                vatAmount,
                totalAmount
            );
            
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error calculating VAT for order {OrderId}", orderId);
            // عدم محاسبه VAT نباید مانع ثبت سفارش شود
            return false;
        }
    }
}
