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

namespace MiningService.API.Application.Commands;

/// <summary>
/// EN: Command to suspend a miner.
/// VI: Command để tạm ngừng thợ đào.
/// </summary>
public record SuspendMinerCommand(Guid MinerId, string Reason) : IRequest<bool>;

public class SuspendMinerCommandHandler : IRequestHandler<SuspendMinerCommand, bool>
{
    private readonly IMinerRepository _minerRepository;

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

    public async Task<bool> Handle(SuspendMinerCommand request, CancellationToken cancellationToken)
    {
        var miner = await _minerRepository.GetByIdAsync(request.MinerId, cancellationToken)
            ?? throw new MinerNotFoundException(request.MinerId);

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

        return true;
    }
}

/// <summary>
/// EN: Command to restore a suspended miner.
/// VI: Command để khôi phục thợ đào bị tạm ngừng.
/// </summary>
public record RestoreMinerCommand(Guid MinerId) : IRequest<bool>;

public class RestoreMinerCommandHandler : IRequestHandler<RestoreMinerCommand, bool>
{
    private readonly IMinerRepository _minerRepository;

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

    public async Task<bool> Handle(RestoreMinerCommand request, CancellationToken cancellationToken)
    {
        var miner = await _minerRepository.GetByIdAsync(request.MinerId, cancellationToken)
            ?? throw new MinerNotFoundException(request.MinerId);

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

        return true;
    }
}
