using CMSMicroservice.Domain.Events;
using CMSMicroservice.Domain.Enums;

namespace CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;

public class ProcessDayaLoanApprovalCommandHandler : IRequestHandler<ProcessDayaLoanApprovalCommand, ProcessDayaLoanApprovalResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<ProcessDayaLoanApprovalResponseDto> Handle(ProcessDayaLoanApprovalCommand request, CancellationToken cancellationToken)
    {
        // پیدا کردن کاربر
        var user = await _context.Users
            .Include(u => u.UserWallets)
            .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
        
        if (user == null)
        {
            throw new NotFoundException(nameof(User), request.UserId);
        }
        
        // چک کردن که قبلاً دریافت نکرده باشد
        if (user.HasReceivedDayaCredit)
        {
            throw new InvalidOperationException($"کاربر {request.UserId} قبلاً اعتبار دایا را دریافت کرده است");
        }
        
        // ایجاد تراکنش با RefId = شماره قرارداد دایا
        var transaction = new Transaction
        {
            Amount = request.WalletAmount + request.LockedWalletAmount + request.DiscountWalletAmount, // 168 میلیون
            Description = $"دریافت اعتبار دایا - قرارداد {request.ContractNumber}",
            PaymentStatus = PaymentStatus.Success,
            PaymentDate = DateTime.UtcNow,
            RefId = request.ContractNumber, // شماره قرارداد دایا
            Type = TransactionType.DepositExternal1
        };
        
        await _context.Transactions.AddAsync(transaction, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);
        
        // یافتن یا ایجاد کیف پول کاربر
        var wallet = user.UserWallets.FirstOrDefault();
        if (wallet == null)
        {
            wallet = new UserWallet
            {
                UserId = request.UserId,
                Balance = 0,
                NetworkBalance = 0,
                DiscountBalance = 0
            };
            await _context.UserWallets.AddAsync(wallet, cancellationToken);
            await _context.SaveChangesAsync(cancellationToken);
        }
        
        // شارژ کیف پول عادی (56 میلیون)
        var balanceBeforeMain = wallet.Balance;
        wallet.Balance += request.WalletAmount;
        
        // لاگ کیف پول عادی
        var mainLog = new UserWalletChangeLog
        {
            WalletId = wallet.Id,
            CurrentBalance = wallet.Balance,
            ChangeValue = request.WalletAmount,
            CurrentNetworkBalance = wallet.NetworkBalance,
            ChangeNerworkValue = 0,
            IsIncrease = true,
            RefrenceId = transaction.Id
        };
        await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
        
        // شارژ کیف پول شبکه/کارمزد (56 میلیون) - نام‌گذاری قدیم: کیف پول قفل شده
        var balanceBeforeLocked = wallet.NetworkBalance;
        wallet.NetworkBalance += request.LockedWalletAmount;
        
        // لاگ کیف پول شبکه
        var networkLog = new UserWalletChangeLog
        {
            WalletId = wallet.Id,
            CurrentBalance = wallet.Balance,
            ChangeValue = 0,
            CurrentNetworkBalance = wallet.NetworkBalance,
            ChangeNerworkValue = request.LockedWalletAmount,
            IsIncrease = true,
            RefrenceId = transaction.Id
        };
        await _context.UserWalletChangeLogs.AddAsync(networkLog, cancellationToken);
        
        // شارژ کیف پول تخفیف (56 میلیون)
        var balanceBeforeDiscount = wallet.DiscountBalance;
        wallet.DiscountBalance += request.DiscountWalletAmount;
        
        // لاگ کیف پول تخفیف
        var discountLog = new UserWalletChangeLog
        {
            WalletId = wallet.Id,
            CurrentBalance = wallet.Balance,
            ChangeValue = 0,
            CurrentNetworkBalance = wallet.NetworkBalance,
            ChangeNerworkValue = 0,
            CurrentDiscountBalance = wallet.DiscountBalance,
            ChangeDiscountValue = request.DiscountWalletAmount,
            IsIncrease = true,
            RefrenceId = transaction.Id
        };
        await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken);
        
        // به‌روزرسانی وضعیت کاربر
        user.HasReceivedDayaCredit = true;
        user.DayaCreditReceivedAt = DateTime.UtcNow;
        
        // تنظیم نحوه خرید پکیج به DayaLoan
        user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan;
        
        // ثبت سفارش پکیج (فعلاً پکیج طلایی)
        var goldenPackage = await _context.Packages
            .FirstOrDefaultAsync(p => p.Title.Contains("طلایی") || p.Title.Contains("Golden"), cancellationToken);
        
        if (goldenPackage != null)
        {
            // پیدا کردن آدرس پیش‌فرض کاربر
            var defaultAddress = await _context.UserAddresses
                .Where(a => a.UserId == request.UserId)
                .OrderByDescending(a => a.Created)
                .FirstOrDefaultAsync(cancellationToken);
            
            if (defaultAddress != null)
            {
                var packageOrder = new UserOrder
                {
                    UserId = request.UserId,
                    PackageId = goldenPackage.Id,
                    Amount = request.WalletAmount, // 56 میلیون
                    PaymentStatus = PaymentStatus.Success,
                    PaymentDate = DateTime.UtcNow,
                    DeliveryStatus = DeliveryStatus.None,
                    UserAddressId = defaultAddress.Id,
                    TransactionId = transaction.Id,
                    PaymentMethod = PaymentMethod.IPG
                };
                
                await _context.UserOrders.AddAsync(packageOrder, cancellationToken);
            }
        }
        
        // ثبت Event
        user.AddDomainEvent(new DayaLoanApprovedEvent(user, transaction, request.ContractNumber));
        
        await _context.SaveChangesAsync(cancellationToken);
        
        return new ProcessDayaLoanApprovalResponseDto
        {
            UserId = user.Id,
            TransactionId = transaction.Id,
            ContractNumber = request.ContractNumber,
            MainWalletBalance = wallet.Balance,
            LockedWalletBalance = wallet.NetworkBalance,
            DiscountWalletBalance = wallet.DiscountBalance,
            Message = "اعتبار دایا با موفقیت دریافت شد"
        };
    }
}
