using MediatR;
using MiningService.Domain.AggregatesModel.MinerAggregate;
using MiningService.Domain.AggregatesModel.CircleAggregate;
using MiningService.Infrastructure;
using Microsoft.EntityFrameworkCore;

namespace MiningService.API.Application.Queries;

/// <summary>
/// EN: Query for admin dashboard overview.
/// VI: Query tổng quan dashboard admin.
/// </summary>
public record GetAdminOverviewQuery() : IRequest<AdminOverviewDto>;

public record AdminOverviewDto(
    int TotalMiners,
    int ActiveMiners,
    int MinersWithActiveSession,
    decimal TotalPointsMined,
    int TotalCircles,
    int ValidCircles,
    int TotalReferrals,
    int ActiveReferrals);

public class GetAdminOverviewQueryHandler : IRequestHandler<GetAdminOverviewQuery, AdminOverviewDto>
{
    private readonly MiningServiceContext _context;

    public GetAdminOverviewQueryHandler(MiningServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<AdminOverviewDto> Handle(GetAdminOverviewQuery request, CancellationToken cancellationToken)
    {
        var totalMiners = await _context.Miners.CountAsync(cancellationToken);
        var activeMiners = await _context.Miners
            .CountAsync(miner => miner.Status == MinerStatus.Active, cancellationToken);
        var minersWithActiveSession = await _context.Miners
            .CountAsync(miner => miner.ActiveSession != null && miner.ActiveSession.Status == MiningSessionStatus.Active, cancellationToken);
        var totalPointsMined = await _context.Miners
            .SumAsync(miner => (decimal?)miner.TotalMinedPoints, cancellationToken) ?? 0m;

        var totalCircles = await _context.Circles.CountAsync(cancellationToken);
        var validCircles = await _context.Circles
            .CountAsync(circle => circle.Status == CircleStatus.Active, cancellationToken);

        var totalReferrals = await _context.Referrals.CountAsync(cancellationToken);
        var activeReferrals = await _context.Referrals
            .CountAsync(referral => referral.IsActive, cancellationToken);

        return new AdminOverviewDto(
            TotalMiners: totalMiners,
            ActiveMiners: activeMiners,
            MinersWithActiveSession: minersWithActiveSession,
            TotalPointsMined: totalPointsMined,
            TotalCircles: totalCircles,
            ValidCircles: validCircles,
            TotalReferrals: totalReferrals,
            ActiveReferrals: activeReferrals);
    }
}
