/**
 * POST /api/now/check — evidence-based progress check for ONE dashboard item.
 *
 * Streams Agent SDK messages over SSE. The frontend renders tool calls
 * inline as the agent works, then parses the final markdown verdict
 * (CLOSE / KEEP / ESCALATE) to drive the per-item action UI.
 */
import type { Hono } from "hono";
import { streamSSE } from "hono/streaming";
import { query } from "@anthropic-ai/claude-agent-sdk";
import { join } from "node:path";
import { MEMORY_DIR } from "./paths";
import { defaultSdkOptions } from "./agent";
import { loadCheckHistory, saveCheckHistory, appendCheck, parseVerdict, itemKey } from "./check-cache";
import { sourcesUsed, activeSourcesPromptBlock } from "./check-sources";
import { addSystemSession } from "./system-sessions";
import { KNITOR_SYSTEM_SENTINEL } from "./chats";
import { posthog, DISTINCT_ID } from "./posthog";

type CheckRequest = {
  file: string;
  line: number;
  source: string;
  kind: string;
  itemText: string;
  daysOff?: number;
  mtime?: number;
};

function buildPrompt(body: CheckRequest): string {
  const today = new Date().toISOString().slice(0, 10);
  const sourcePath = join(MEMORY_DIR, body.file);

  const ageHint =
    body.kind === "stalled"
      ? `It's been flagged as stalled because the project file hasn't been edited in ~${Math.abs(body.daysOff || 0)} days.`
      : body.kind === "overdue"
      ? `It's overdue by ~${Math.abs(body.daysOff || 0)} days based on a date in the source.`
      : body.kind === "today"
      ? `Date target is today.`
      : `It's an open loop (no firm date, but the source flagged it as awaiting/blocked/decision).`;

  return `${KNITOR_SYSTEM_SENTINEL}
You are evaluating ONE flagged item from Pavel Racu's "what needs your attention" dashboard.

ITEM:
- Source label: ${body.source}
- Kind: ${body.kind} — ${ageHint}
- Source file: ${sourcePath}:${body.line}
- Item text: """${body.itemText.slice(0, 600)}"""

Today is ${today}. Pavel is Head of Product at AWSsome.

YOUR JOB — BE EFFICIENT (3–6 tool calls MAX):
Determine if there's evidence this item has been progressed or resolved since it was flagged. Use the most appropriate sources for the topic:
${activeSourcesPromptBlock()}

Pick 2–3 of the above based on what makes sense for this item. Don't search every source for everything.

OUTPUT — strict markdown, no preamble:
## VERDICT: CLOSE | KEEP | ESCALATE

[1–2 sentences why.]

**Evidence:**
- [date] [source] — concrete finding (with link/path/issue ID if available)
- …(2–4 bullets max)

**Suggested resolution:**
[If CLOSE: 1–2 sentences Pavel can paste verbatim as the resolution. If KEEP/ESCALATE: a clear next action and who owns it.]
`;
}

export function registerCheckRoutes(app: Hono) {
  app.post("/api/now/check", async (c) => {
    const body = await c.req.json<CheckRequest>();
    const prompt = buildPrompt(body);

    return streamSSE(c, async (stream) => {
      let raw = "";
      const toolNames: string[] = [];
      try {
        for await (const msg of query({
          prompt,
          options: defaultSdkOptions({ maxTurns: 8 }) as any,
        })) {
          const m = msg as any;
          // Tag this as a system-initiated session so the chat list filters it out.
          if (m.type === "system" && m.subtype === "init" && typeof m.session_id === "string") {
            addSystemSession(m.session_id);
          }
          if (m.type === "assistant" && m.message?.content) {
            for (const block of m.message.content) {
              if (block.type === "text" && typeof block.text === "string") raw += block.text;
              else if (block.type === "tool_use" && typeof block.name === "string") toolNames.push(block.name);
            }
          }
          await stream.writeSSE({ data: JSON.stringify(msg), event: "message" });
        }
        // Append verdict + sources to history so the dashboard can render
        // the latest inline AND show prior runs on demand.
        if (raw.trim()) {
          const parsed = parseVerdict(raw);
          const history = loadCheckHistory();
          appendCheck(history, itemKey(body.file, body.line, body.itemText), {
            checkedAt: new Date().toISOString(),
            ...parsed,
            sourcesUsed: sourcesUsed(toolNames),
          });
          saveCheckHistory(history);
          posthog.capture({
            distinctId: DISTINCT_ID,
            event: "item check completed",
            properties: {
              verdict: parsed.verdict,
              source: body.source,
              kind: body.kind,
              sources_used: sourcesUsed(toolNames),
              days_off: body.daysOff,
            },
          });
        }
        await stream.writeSSE({ data: "done", event: "done" });
      } catch (err: any) {
        posthog.captureException(err, DISTINCT_ID);
        await stream.writeSSE({
          data: JSON.stringify({ error: err?.message || String(err) }),
          event: "error",
        });
      }
    });
  });
}
