import { isPlainObject } from "@/lib/type-guards";

export type HermesBridgeConfig = {
  baseUrl: string;
  apiKey: string | null;
};

export type HermesRunRequest = {
  input: Array<{ role: string; content: string }> | string;
  instructions?: string;
  conversation_history?: Array<{ role: string; content: string }>;
  session_id?: string;
};

export type HermesRunStarted = {
  runId: string;
};

export type HermesRunEvent =
  | { event: "tool.started"; tool: string; preview?: string | null }
  | { event: "tool.completed"; tool: string; duration?: number; error?: boolean }
  | { event: "message.delta"; delta: string }
  | { event: "run.completed"; output?: string; usage?: Record<string, unknown> }
  | { event: "run.failed"; error?: string }
  | { event: string; [key: string]: unknown };

const DEFAULT_BASE_URL = "http://127.0.0.1:8642";

const trimTrailingSlash = (value: string) => value.replace(/\/+$/, "");

export const readHermesBridgeConfig = (): HermesBridgeConfig => ({
  baseUrl: trimTrailingSlash((process.env.MNOTE_HERMES_API_BASE_URL || "").trim() || DEFAULT_BASE_URL),
  apiKey: (process.env.MNOTE_HERMES_API_KEY || "").trim() || null,
});

export const buildHermesHeaders = (config: HermesBridgeConfig, init?: HeadersInit) => {
  const headers = new Headers(init);
  headers.set("Content-Type", "application/json");
  if (config.apiKey) {
    headers.set("Authorization", `Bearer ${config.apiKey}`);
  }
  return headers;
};

export const startHermesRun = async (payload: HermesRunRequest): Promise<HermesRunStarted> => {
  const config = readHermesBridgeConfig();
  const response = await fetch(`${config.baseUrl}/v1/runs`, {
    method: "POST",
    headers: buildHermesHeaders(config),
    body: JSON.stringify(payload),
    cache: "no-store",
  });

  if (!response.ok) {
    const text = await response.text().catch(() => "");
    throw new Error(text || `Hermes run 启动失败：HTTP ${response.status}`);
  }

  const json = (await response.json().catch(() => null)) as unknown;
  const runId = isPlainObject(json) ? String(json.run_id ?? "").trim() : "";
  if (!runId) throw new Error("Hermes run 响应缺少 run_id");
  return { runId };
};

export const streamHermesRunEvents = async (
  runId: string,
  onEvent: (event: HermesRunEvent) => Promise<void> | void,
) => {
  const config = readHermesBridgeConfig();
  const response = await fetch(`${config.baseUrl}/v1/runs/${encodeURIComponent(runId)}/events`, {
    method: "GET",
    headers: buildHermesHeaders(config),
    cache: "no-store",
  });

  if (!response.ok) {
    const text = await response.text().catch(() => "");
    throw new Error(text || `Hermes 事件流连接失败：HTTP ${response.status}`);
  }
  if (!response.body) throw new Error("Hermes 事件流不支持 body");

  const reader = response.body.getReader();
  const decoder = new TextDecoder("utf-8");
  let buffer = "";

  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });

    while (true) {
      const sep = buffer.indexOf("\n\n");
      if (sep === -1) break;
      const raw = buffer.slice(0, sep);
      buffer = buffer.slice(sep + 2);

      if (raw.trimStart().startsWith(":")) continue;

      const dataLines = raw
        .split(/\r?\n/)
        .filter((line) => line.startsWith("data:"))
        .map((line) => line.slice("data:".length).trimStart());
      if (dataLines.length === 0) continue;

      let parsed: unknown = null;
      try {
        parsed = JSON.parse(dataLines.join("\n"));
      } catch {
        continue;
      }
      if (!isPlainObject(parsed)) continue;
      await onEvent(parsed as HermesRunEvent);
    }
  }
};
