using AdsBillingService.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace AdsBillingService.API.Application.Commands;

/// <summary>
/// EN: Command to add funds to a billing account.
/// VI: Command nạp tiền vào tài khoản billing.
/// </summary>
public record AddFundsCommand(Guid AccountId, decimal Amount) : IRequest<bool>;

/// <summary>
/// EN: Handler for AddFundsCommand.
/// VI: Handler cho AddFundsCommand.
/// </summary>
public class AddFundsCommandHandler : IRequestHandler<AddFundsCommand, bool>
{
    private readonly AdsBillingServiceContext _context;
    private readonly ILogger<AddFundsCommandHandler> _logger;

    public AddFundsCommandHandler(
        AdsBillingServiceContext context,
        ILogger<AddFundsCommandHandler> logger)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<bool> Handle(AddFundsCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Adding {Amount} funds to account {AccountId}", request.Amount, request.AccountId);

        // EN: Get account from database / VI: Lấy tài khoản từ database
        var account = await _context.BillingAccounts
            .FirstOrDefaultAsync(a => a.Id == request.AccountId, cancellationToken);

        if (account == null)
        {
            _logger.LogWarning("Account {AccountId} not found", request.AccountId);
            return false;
        }

        // EN: Add funds using domain method / VI: Nạp tiền sử dụng domain method
        account.AddBalance(request.Amount);

        // EN: Save changes / VI: Lưu thay đổi
        await _context.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Successfully added {Amount} funds to account {AccountId}", 
            request.Amount, request.AccountId);

        return true;
    }
}
