using FastEndpoints;
using Microsoft.Extensions.Logging;

namespace KArtSell.Host.Features.ShadowRun;

/// <summary>
/// GET /api/shadow-runs/{run_id}
/// Poll shadow run status and retrieve results.
/// Returns 200 with status (in progress) or 200 with metrics (complete).
/// </summary>
public class GetShadowRunPollingEndpoint : Endpoint<GetShadowRunPollingRequest, GetShadowRunResponse>
{
    private GetShadowRunQuery? _query;
    private ILogger<GetShadowRunPollingEndpoint>? _logger;

    private static readonly Action<ILogger, Guid, Exception?> LogPolling =
        LoggerMessage.Define<Guid>(
            LogLevel.Debug,
            new EventId(1, nameof(LogPolling)),
            "Polling shadow run {RunId}");

    private static readonly Action<ILogger, Guid, Exception?> LogNotFound =
        LoggerMessage.Define<Guid>(
            LogLevel.Information,
            new EventId(2, nameof(LogNotFound)),
            "Shadow run {RunId} not found");

    public override void Configure()
    {
        Get("/shadow-runs/{RunId}");  // RoutePrefix "api" added automatically in Program.cs
        Roles("Admin", "Analyst", "Researcher");  // RBAC: Admin, Analyst, or Researcher can poll (Gate 3 testing)
    }

    public override async Task HandleAsync(GetShadowRunPollingRequest req, CancellationToken ct)
    {
        _query = Resolve<GetShadowRunQuery>();
        _logger = Resolve<ILogger<GetShadowRunPollingEndpoint>>();

        LogPolling(_logger, req.RunId, null);

        var result = await _query.GetAsync(req.RunId, ct);

        if (result == null)
        {
            LogNotFound(_logger, req.RunId, null);
            ThrowError($"Shadow run {req.RunId} not found", 404);
            return;
        }

        HttpContext.Response.StatusCode = 200;
        await HttpContext.Response.WriteAsJsonAsync(result, ct);
    }
}

public sealed record GetShadowRunPollingRequest(Guid RunId);
