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

namespace MiningService.API.Application.Queries;

/// <summary>
/// EN: Query to get referral code.
/// VI: Query để lấy mã giới thiệu.
/// </summary>
public record GetReferralCodeQuery(Guid UserId) : IRequest<ReferralCodeDto?>;

public record ReferralCodeDto(string ReferralCode, string ShareUrl);

public class GetReferralCodeQueryHandler : IRequestHandler<GetReferralCodeQuery, ReferralCodeDto?>
{
    private readonly IMinerRepository _minerRepository;

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

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

        var shareUrl = $"https://goodgo.app/invite/{miner.ReferralCode}";
        return new ReferralCodeDto(miner.ReferralCode, shareUrl);
    }
}

/// <summary>
/// EN: Query to get referral statistics.
/// VI: Query để lấy thống kê giới thiệu.
/// </summary>
public record GetReferralStatsQuery(Guid UserId) : IRequest<ReferralStatsDto?>;

public record ReferralStatsDto(
    string ReferralCode,
    int TotalReferrals,
    int ActiveReferrals,
    int PendingReferrals,
    decimal TotalEarned,
    decimal CurrentBonusRate);

public class GetReferralStatsQueryHandler : IRequestHandler<GetReferralStatsQuery, ReferralStatsDto?>
{
    private readonly IMinerRepository _minerRepository;
    private readonly IReferralRepository _referralRepository;

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

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

        var referrals = await _referralRepository.GetByReferrerIdAsync(miner.Id, cancellationToken);
        var activeCount = referrals.Count(r => r.IsActive);
        var pendingCount = referrals.Count(r => !r.IsActive);
        var totalEarned = referrals.Where(r => r.IsActive).Sum(r => r.BonusRate * 100); // Simplified
        var bonusRate = Math.Min(activeCount * 0.25m, 1.0m);

        return new ReferralStatsDto(
            miner.ReferralCode,
            referrals.Count,
            activeCount,
            pendingCount,
            totalEarned,
            bonusRate);
    }
}
