using MediatR;
using MiningService.Domain.AggregatesModel.MinerAggregate;
using MiningService.Domain.Exceptions;

namespace MiningService.API.Application.Commands;

/// <summary>
/// EN: Handler for ClaimMiningRewardCommand.
/// VI: Handler cho ClaimMiningRewardCommand.
/// </summary>
public class ClaimMiningRewardCommandHandler : IRequestHandler<ClaimMiningRewardCommand, ClaimMiningRewardResult>
{
    private readonly IMinerRepository _minerRepository;

    public ClaimMiningRewardCommandHandler(IMinerRepository minerRepository)
    {
        _minerRepository = minerRepository;
    }

    public async Task<ClaimMiningRewardResult> Handle(ClaimMiningRewardCommand request, CancellationToken cancellationToken)
    {
        var miner = await _minerRepository.GetByUserIdAsync(request.UserId, cancellationToken)
            ?? throw new MinerNotFoundException($"Miner with UserId {request.UserId} not found");

        var pointsEarned = miner.ClaimMiningReward();

        _minerRepository.Update(miner);
        await _minerRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return new ClaimMiningRewardResult(
            pointsEarned,
            miner.TotalMinedPoints,
            miner.Streak.CurrentStreak,
            miner.Streak.BonusMultiplier);
    }
}
