namespace WalletService.API.Application.Commands;

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

/// <summary>
/// EN: Handler for CreatePointAccountCommand
/// VI: Handler cho CreatePointAccountCommand
/// </summary>
public class CreatePointAccountCommandHandler : IRequestHandler<CreatePointAccountCommand, CreatePointAccountResult>
{
    private readonly IPointAccountRepository _pointAccountRepository;
    private readonly ILogger<CreatePointAccountCommandHandler> _logger;

    public CreatePointAccountCommandHandler(
        IPointAccountRepository pointAccountRepository,
        ILogger<CreatePointAccountCommandHandler> logger)
    {
        _pointAccountRepository = pointAccountRepository;
        _logger = logger;
    }

    public async Task<CreatePointAccountResult> Handle(
        CreatePointAccountCommand request,
        CancellationToken cancellationToken)
    {
        // EN: Check if user already has a point account
        // VI: Kiểm tra xem user đã có tài khoản điểm chưa
        var exists = await _pointAccountRepository.ExistsByUserIdAsync(request.UserId);
        if (exists)
        {
            throw new PointsDomainException($"User {request.UserId} already has a point account");
        }

        // EN: Create new point account
        // VI: Tạo tài khoản điểm mới
        var account = new PointAccount(request.UserId);

        _pointAccountRepository.Add(account);
        await _pointAccountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Created point account {AccountId} for user {UserId}",
            account.Id, request.UserId);

        return new CreatePointAccountResult(
            account.Id,
            account.UserId,
            account.TotalPoints,
            account.AvailablePoints,
            account.CreatedAt
        );
    }
}
