import { NextResponse } from "next/server";
import { run } from "@/lib/runner";
import { FCC_BASE, FCC_TOKEN, probeReachable } from "@/lib/fcc";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

const TIMEOUT_MS = 6 * 60 * 1000;

async function callFcc(prompt: string): Promise<{ text: string; durationMs: number }> {
  const started = Date.now();
  const ctl = new AbortController();
  const tid = setTimeout(() => ctl.abort(), TIMEOUT_MS);
  try {
    const r = await fetch(`${FCC_BASE}/v1/messages`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": FCC_TOKEN,
        "anthropic-version": "2023-06-01",
      },
      body: JSON.stringify({
        model: "open_router/google/gemma-4-31b-it:free",
        messages: [{ role: "user", content: prompt }],
        max_tokens: 8192,
      }),
      signal: ctl.signal,
    });
    clearTimeout(tid);
    if (!r.ok) {
      const errBody = await r.text().catch(() => "");
      throw new Error(`FCC returned ${r.status}: ${errBody}`);
    }
    const body = await r.json();
    const text = body?.content?.[0]?.text?.trim() || "(no response)";
    return { text, durationMs: Date.now() - started };
  } catch (e) {
    clearTimeout(tid);
    throw e;
  }
}

export async function POST(req: Request) {
  const { prompt } = await req.json();
  if (typeof prompt !== "string" || prompt.length === 0) {
    return NextResponse.json({ error: "missing prompt" }, { status: 400 });
  }
  if (prompt.length > 16_000) {
    return NextResponse.json({ error: "prompt too long" }, { status: 413 });
  }

  const fccReachable = await probeReachable();

  if (fccReachable) {
    try {
      const { text, durationMs } = await callFcc(prompt);
      return NextResponse.json({
        ok: true,
        text,
        empty: !text,
        durationMs,
        exitCode: 0,
        timedOut: false,
        stderr: "",
        source: "fcc",
      });
    } catch (e) {
      const errMsg = e instanceof Error ? e.message : String(e);
      return NextResponse.json({
        ok: false,
        text: `FCC error: ${errMsg}`,
        empty: true,
        durationMs: 0,
        exitCode: -1,
        timedOut: false,
        stderr: errMsg,
        source: "fcc",
      });
    }
  }

  // Fallback to Hermes CLI when FCC is not reachable
  const out = await run("hermes", ["-z", prompt, "--yolo", "--accept-hooks"], { timeoutMs: TIMEOUT_MS });

  const ANSI_STRIP = /\x1b\[[0-9;?]*[a-zA-Z]|\x1b\]\d+;[^\x07\x1b]*(\x07|\x1b\\)/g;
  const text = out.stdout.replace(ANSI_STRIP, "").trim();
  const stderrClean = out.stderr.replace(ANSI_STRIP, "").trim();

  let diagnostic: string | null = null;
  if (!text) {
    const seconds = (out.durationMs / 1000).toFixed(1);
    const probableTimeout = out.durationMs >= TIMEOUT_MS - 2_000;
    const lines: string[] = [];
    lines.push(probableTimeout
      ? `Hermes was killed after ${seconds}s — the task likely needed longer than the ${Math.round(TIMEOUT_MS/60000)}-minute budget.`
      : `Hermes finished in ${seconds}s with exit ${out.code} but no stdout.`
    );
    if (stderrClean) {
      lines.push("", "--- stderr ---");
      lines.push(stderrClean.length > 4000 ? stderrClean.slice(-4000) : stderrClean);
    } else {
      lines.push("", "(no stderr either)");
    }
    diagnostic = lines.join("\n");
  }

  return NextResponse.json({
    ok: out.ok && !!text,
    text: text || diagnostic || "(no response)",
    empty: !text,
    durationMs: out.durationMs,
    exitCode: out.code,
    timedOut: !text && out.durationMs >= TIMEOUT_MS - 2_000,
    stderr: stderrClean,
    source: "hermes",
  });
}
