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

namespace MiningService.API.Application.Queries;

/// <summary>
/// EN: Query to get miner status.
/// VI: Query để lấy trạng thái thợ đào.
/// </summary>
public record GetMinerStatusQuery(Guid UserId) : IRequest<MinerStatusDto?>;

public record MinerStatusDto(
    Guid MinerId,
    string Role,
    decimal TotalMinedPoints,
    decimal HourlyRate,
    decimal DailyRate,
    int CurrentStreak,
    int LongestStreak,
    decimal StreakBonus,
    bool HasActiveSession,
    DateTime? SessionEndTime,
    string Status);

public class GetMinerStatusQueryHandler : IRequestHandler<GetMinerStatusQuery, MinerStatusDto?>
{
    private readonly IMinerRepository _minerRepository;

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

    public async Task<MinerStatusDto?> Handle(GetMinerStatusQuery request, CancellationToken cancellationToken)
    {
        var miner = await _minerRepository.GetByUserIdAsync(request.UserId, cancellationToken);
        if (miner == null) return null;

        return new MinerStatusDto(
            miner.Id,
            miner.Role.ToString(),
            miner.TotalMinedPoints,
            miner.CurrentRate.TotalRate,
            miner.CurrentRate.DailyRate,
            miner.Streak.CurrentStreak,
            miner.Streak.LongestStreak,
            miner.Streak.BonusMultiplier,
            miner.ActiveSession?.Status == MiningSessionStatus.Active,
            miner.ActiveSession?.EndTime,
            miner.Status.ToString());
    }
}
