import type { CapturedLog } from "../proxy/schemas";

export type StopReason = "end_turn" | "tool_use" | "stop" | null;

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

/**
 * Extracts the stop/finish reason from a captured log's response text.
 * Detects the response body shape (Anthropic or OpenAI) independently of
 * `log.apiFormat`, since the body shape may not match the declared format
 * (e.g. an Anthropic-compatible endpoint returning Anthropic-shaped JSON
 * while the request was classified as OpenAI).
 */
export function extractStopReason(log: CapturedLog): StopReason {
  if (log.responseText === null) return null;

  try {
    let json: unknown = JSON.parse(log.responseText);
    // Handle double-encoded JSON
    if (typeof json === "string") {
      json = JSON.parse(json);
    }
    if (!isRecord(json)) return null;

    // Anthropic shape: { stop_reason: "end_turn" | "tool_use" | ... }
    if (typeof json.stop_reason === "string") {
      if (json.stop_reason === "end_turn" || json.stop_reason === "tool_use") {
        return json.stop_reason;
      }
      return null;
    }

    // OpenAI shape: { choices: [{ finish_reason: "stop" | ... }] }
    if (
      Array.isArray(json.choices) &&
      json.choices.length > 0 &&
      isRecord(json.choices[0]) &&
      typeof json.choices[0].finish_reason === "string" &&
      json.choices[0].finish_reason === "stop"
    ) {
      return "stop";
    }

    return null;
  } catch {
    return null;
  }
}

/**
 * Returns true when the stop reason indicates the assistant completed its
 * turn naturally (Anthropic end_turn or OpenAI stop).
 */
export function isTurnBoundary(stopReason: StopReason): boolean {
  return stopReason === "end_turn" || stopReason === "stop";
}
