using MediatR;
using Microsoft.EntityFrameworkCore;
using Workflow.Application.Features.WorkflowInstances.DTOs;
using Workflow.Infrastructure.Persistence;

namespace Workflow.Application.Features.WorkflowInstances.Queries;

public record MonitorWorkflowInstancesQuery : IRequest<WorkflowMonitorDto>;

public class MonitorWorkflowInstancesQueryHandler(WorkflowDbContext db)
    : IRequestHandler<MonitorWorkflowInstancesQuery, WorkflowMonitorDto>
{
    public async Task<WorkflowMonitorDto> Handle(MonitorWorkflowInstancesQuery request, CancellationToken cancellationToken)
    {
        var totalInstances = await db.WorkflowInstances.CountAsync(cancellationToken);
        var runningInstances = await db.WorkflowInstances.CountAsync(i => i.Status == InstanceStatus.Running, cancellationToken);
        var suspendedInstances = await db.WorkflowInstances.CountAsync(i => i.Status == InstanceStatus.Suspended, cancellationToken);
        var completedInstances = await db.WorkflowInstances.CountAsync(i => i.Status == InstanceStatus.Completed, cancellationToken);
        var terminatedInstances = await db.WorkflowInstances.CountAsync(i => i.Status == InstanceStatus.Terminated, cancellationToken);

        var pendingTasks = await db.WorkflowTasks.CountAsync(t => t.Status == TaskStatus.Pending, cancellationToken);
        var overdueTasks = await db.WorkflowTasks
            .CountAsync(t => t.Status == TaskStatus.Pending && t.DueAt != null && t.DueAt < DateTime.UtcNow, cancellationToken);

        return new WorkflowMonitorDto(
            totalInstances,
            runningInstances,
            suspendedInstances,
            completedInstances,
            terminatedInstances,
            pendingTasks,
            overdueTasks
        );
    }
}
