import { type NextRequest, NextResponse } from "next/server";

const DEFAULT_ORCHESTRATOR_URL = "http://localhost:3001";

function getOrchestratorUrl(): string {
  return (
    process.env.ORCHESTRATOR_URL ??
    process.env.NEXT_PUBLIC_ORCHESTRATOR_URL ??
    process.env.NEXT_PUBLIC_API_URL ??
    DEFAULT_ORCHESTRATOR_URL
  );
}

/**
 * Generic catch-all proxy for orchestrator API routes.
 *
 * Forwards any request to /api/orchestrator/<path> → ORCHESTRATOR_URL/<path>
 * with the ORCHESTRATOR_API_KEY injected server-side so it never reaches the browser.
 *
 * Supports GET, POST, PATCH, DELETE, PUT.
 *
 * Example:
 *   GET  /api/orchestrator/mission-control/sessions
 *     → GET ORCHESTRATOR_URL/api/mission-control/sessions
 *   POST /api/orchestrator/mission-control/sessions/abc/kill
 *     → POST ORCHESTRATOR_URL/api/mission-control/sessions/abc/kill
 */
async function proxyToOrchestrator(
  request: NextRequest,
  context: { params: Promise<{ path: string[] }> }
): Promise<NextResponse> {
  const orchestratorApiKey = process.env.ORCHESTRATOR_API_KEY;
  if (!orchestratorApiKey) {
    return NextResponse.json(
      { error: "ORCHESTRATOR_API_KEY is not configured on the web server." },
      { status: 503 }
    );
  }

  const { path } = await context.params;
  const upstreamPath = `/${path.join("/")}`;
  const search = request.nextUrl.search;
  const upstreamUrl = `${getOrchestratorUrl()}${upstreamPath}${search}`;

  const controller = new AbortController();
  const timeout = setTimeout(() => {
    controller.abort();
  }, 30_000);

  try {
    const headers: Record<string, string> = {
      "X-API-Key": orchestratorApiKey,
    };

    const contentType = request.headers.get("Content-Type");
    if (contentType) {
      headers["Content-Type"] = contentType;
    }

    const hasBody = request.method !== "GET" && request.method !== "HEAD";
    const body = hasBody ? await request.text() : null;

    const upstream = await fetch(upstreamUrl, {
      method: request.method,
      headers,
      ...(body !== null ? { body } : {}),
      cache: "no-store",
      signal: controller.signal,
    });

    const responseText = await upstream.text();
    return new NextResponse(responseText, {
      status: upstream.status,
      headers: {
        "Content-Type": upstream.headers.get("Content-Type") ?? "application/json",
      },
    });
  } catch (error) {
    const message =
      error instanceof Error && error.name === "AbortError"
        ? "Orchestrator request timed out."
        : "Unable to reach orchestrator.";
    return NextResponse.json({ error: message }, { status: 502 });
  } finally {
    clearTimeout(timeout);
  }
}

export const GET = proxyToOrchestrator;
export const POST = proxyToOrchestrator;
export const PATCH = proxyToOrchestrator;
export const PUT = proxyToOrchestrator;
export const DELETE = proxyToOrchestrator;
