using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Runner;
using Microsoft.AspNetCore.Http;

namespace ClaudeDo.Worker.Planning;

public sealed class PlanningTokenAuthMiddleware
{
    private readonly RequestDelegate _next;

    public PlanningTokenAuthMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext ctx, TaskRepository tasks, TaskRunTokenRegistry runTokens)
    {
        if (!ctx.Request.Path.StartsWithSegments("/mcp"))
        {
            await _next(ctx);
            return;
        }

        var auth = ctx.Request.Headers["Authorization"].ToString();
        if (!auth.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
        {
            ctx.Response.StatusCode = 401;
            await ctx.Response.WriteAsync("Missing bearer token");
            return;
        }

        var token = auth.Substring("Bearer ".Length).Trim();

        var parent = await tasks.FindByPlanningTokenAsync(token, ctx.RequestAborted);
        if (parent is not null && parent.PlanningPhase == ClaudeDo.Data.Models.PlanningPhase.Active)
        {
            ctx.Items["PlanningContext"] = new PlanningMcpContext { ParentTaskId = parent.Id };
            await _next(ctx);
            return;
        }

        if (runTokens.TryResolve(token, out var callerTaskId))
        {
            ctx.Items["TaskRunContext"] = new TaskRunMcpContext { CallerTaskId = callerTaskId };
            await _next(ctx);
            return;
        }

        ctx.Response.StatusCode = 401;
        await ctx.Response.WriteAsync("Invalid or expired token");
    }
}
