namespace WalletService.API.Application.Commands;

using MediatR;
using WalletService.Domain.AggregatesModel.WalletAggregate;
using WalletService.Domain.Exceptions;

/// <summary>
/// EN: Handler for CreateWalletCommand.
/// VI: Handler cho CreateWalletCommand.
/// </summary>
public class CreateWalletCommandHandler : IRequestHandler<CreateWalletCommand, CreateWalletResult>
{
    private readonly IWalletRepository _walletRepository;
    private readonly ILogger<CreateWalletCommandHandler> _logger;

    public CreateWalletCommandHandler(
        IWalletRepository walletRepository,
        ILogger<CreateWalletCommandHandler> logger)
    {
        _walletRepository = walletRepository;
        _logger = logger;
    }

    public async Task<CreateWalletResult> Handle(
        CreateWalletCommand request,
        CancellationToken cancellationToken)
    {
        // EN: Check if user already has a wallet
        // VI: Kiểm tra xem user đã có ví chưa
        var existingWallet = await _walletRepository.ExistsByUserIdAsync(request.UserId);
        if (existingWallet)
        {
            throw new WalletDomainException($"User {request.UserId} already has a wallet");
        }

        // EN: Parse currency string to CurrencyType
        // VI: Parse chuỗi tiền tệ sang CurrencyType
        CurrencyType currencyType;
        try
        {
            currencyType = CurrencyType.FromDisplayName<CurrencyType>(request.Currency.ToUpperInvariant());
        }
        catch
        {
            // EN: Default to VND if currency not found
            // VI: Mặc định là VND nếu không tìm thấy tiền tệ
            currencyType = CurrencyType.VND;
        }

        // EN: Create new wallet with CurrencyType
        // VI: Tạo ví mới với CurrencyType
        var wallet = new Wallet(request.UserId, currencyType);

        _walletRepository.Add(wallet);
        await _walletRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Created wallet {WalletId} for user {UserId} with currency {Currency}",
            wallet.Id, request.UserId, currencyType.Name);

        // EN: Get default currency balance
        // VI: Lấy số dư tiền tệ mặc định
        var defaultBalance = wallet.GetBalance(currencyType);

        return new CreateWalletResult(
            wallet.Id,
            wallet.UserId,
            defaultBalance,
            currencyType.Name,
            wallet.Status.Name,
            wallet.CreatedAt
        );
    }
}
