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

namespace MembershipService.API.Application.Commands;

/// <summary>
/// EN: Handler for resetting a stamp card to start a new round.
/// VI: Handler de reset stamp card bat dau vong moi.
/// </summary>
public class ResetStampCardCommandHandler : IRequestHandler<ResetStampCardCommand, ResetStampCardResult>
{
    private readonly IStampCardRepository _stampCardRepository;
    private readonly ILogger<ResetStampCardCommandHandler> _logger;

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

    public async Task<ResetStampCardResult> Handle(ResetStampCardCommand 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: Reset the card (domain validates reward was claimed)
        // VI: Reset card (domain kiem tra thuong da duoc nhan)
        stampCard.Reset();
        _stampCardRepository.Update(stampCard);
        await _stampCardRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Stamp card {StampCardId} reset for new round", stampCard.Id);

        return new ResetStampCardResult(
            stampCard.Id,
            stampCard.CurrentStamps,
            stampCard.TotalStampsRequired,
            "Stamp card reset for a new round! / Stamp card da reset cho vong moi!");
    }
}
