using AdsBillingService.Domain.AggregatesModel.ChargeAggregate;
using MediatR;

namespace AdsBillingService.API.Application.Commands;

/// <summary>
/// EN: Handler for ChargeAdvertiserCommand - processes ad charges and debits from wallet.
/// VI: Handler cho ChargeAdvertiserCommand - xử lý charge quảng cáo và trừ tiền từ ví.
/// </summary>
public class ChargeAdvertiserCommandHandler : IRequestHandler<ChargeAdvertiserCommand, bool>
{
    private readonly ILogger<ChargeAdvertiserCommandHandler> _logger;
    // private readonly IWalletService _walletService;

    public ChargeAdvertiserCommandHandler(ILogger<ChargeAdvertiserCommandHandler> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<bool> Handle(ChargeAdvertiserCommand request, CancellationToken cancellationToken)
    {
        // Step 1: Create charge record
        var chargeType = request.ChargeType.ToLower() == "impression" 
            ? ChargeType.Impression 
            : ChargeType.Click;

        var charge = new AdCharge(
            request.AdvertiserId,
            request.CampaignId,
            request.AdId,
            chargeType,
            request.Amount
        );

        // TODO: Step 2 - Debit from Wallet Service
        // var walletDebitResult = await _walletService.DebitBalance(
        //     advertiserId: request.AdvertiserId,
        //     amount: request.Amount,
        //     reference: charge.Id,
        //     description: $"Ad {chargeType} charge"
        // );

        // if (!walletDebitResult.Success)
        // {
        //     _logger.LogWarning("Failed to debit wallet for advertiser {AdvertiserId}", request.AdvertiserId);
        //     return false;
        // }

        // Step 3: Mark as processed
        charge.MarkAsProcessed();

        // TODO: Step 4 - Save to repository
        // _adChargeRepository.Add(charge);
        // await _adChargeRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Charged advertiser {AdvertiserId} amount {Amount} for {ChargeType}",
            request.AdvertiserId, request.Amount, chargeType);

        return true;
    }
}
