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

namespace MiningService.API.Application.Queries;

/// <summary>
/// EN: Query to get user's referrals.
/// VI: Query để lấy danh sách giới thiệu.
/// </summary>
public record GetReferralsQuery(Guid UserId) : IRequest<ReferralsDto>;

public record ReferralsDto(
    string MyReferralCode,
    int TotalReferrals,
    int ActiveReferrals,
    decimal TotalBonusPercent,
    List<ReferralDto> Referrals);

public record ReferralDto(
    Guid ReferralId,
    Guid ReferredId,
    bool IsActive,
    DateTime CreatedAt,
    DateTime? ActivatedAt);

public class GetReferralsQueryHandler : IRequestHandler<GetReferralsQuery, ReferralsDto>
{
    private readonly IReferralRepository _referralRepository;
    private readonly IMinerRepository _minerRepository;

    public GetReferralsQueryHandler(
        IReferralRepository referralRepository,
        IMinerRepository minerRepository)
    {
        _referralRepository = referralRepository;
        _minerRepository = minerRepository;
    }

    public async Task<ReferralsDto> Handle(GetReferralsQuery request, CancellationToken cancellationToken)
    {
        var miner = await _minerRepository.GetByUserIdAsync(request.UserId, cancellationToken);
        if (miner == null)
            return new ReferralsDto("", 0, 0, 0, new List<ReferralDto>());

        var referrals = await _referralRepository.GetByReferrerIdAsync(miner.Id, cancellationToken);
        var activeCount = referrals.Count(r => r.IsActive);
        var bonusPercent = Math.Min(activeCount * 0.25m, 1.0m); // 25% per referral, max 100%

        return new ReferralsDto(
            miner.ReferralCode,
            referrals.Count,
            activeCount,
            bonusPercent,
            referrals.Select(r => new ReferralDto(
                r.Id,
                r.ReferredId,
                r.IsActive,
                r.CreatedAt,
                r.ActivatedAt
            )).ToList());
    }
}
