using MediatR;
using MembershipService.Domain.AggregatesModel.StampCardAggregate;

namespace MembershipService.API.Application.Commands;

/// <summary>
/// EN: Handler for claiming a reward on a completed stamp card.
/// VI: Handler de nhan thuong tren stamp card da hoan thanh.
/// </summary>
public class ClaimRewardCommandHandler : IRequestHandler<ClaimRewardCommand, ClaimRewardResult>
{
    private readonly IStampCardRepository _stampCardRepository;
    private readonly ILogger<ClaimRewardCommandHandler> _logger;

    public ClaimRewardCommandHandler(
        IStampCardRepository stampCardRepository,
        ILogger<ClaimRewardCommandHandler> logger)
    {
        _stampCardRepository = stampCardRepository ?? throw new ArgumentNullException(nameof(stampCardRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<ClaimRewardResult> Handle(ClaimRewardCommand request, CancellationToken cancellationToken)
    {
        // EN: Find the stamp card
        // VI: Tim stamp card
        var stampCard = await _stampCardRepository.GetByIdAsync(request.StampCardId, cancellationToken);
        if (stampCard == null)
        {
            throw new KeyNotFoundException(
                $"Stamp card {request.StampCardId} not found / Stamp card {request.StampCardId} khong tim thay");
        }

        // EN: Claim the reward (domain validates completion)
        // VI: Nhan thuong (domain kiem tra hoan thanh)
        stampCard.ClaimReward();
        _stampCardRepository.Update(stampCard);
        await _stampCardRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Reward claimed on stamp card {StampCardId} for member {MemberId}",
            stampCard.Id, stampCard.MemberId);

        return new ClaimRewardResult(
            stampCard.Id,
            true,
            "Reward claimed successfully! / Nhan thuong thanh cong!");
    }
}
