import { codeQueuePromptResponseFields, type JsonRecord } from "../src/components/microservices/code-queue-mgr/src/prompt-observation";

function assertCondition(condition: unknown, message: string, detail: JsonRecord = {}): void {
  if (!condition) {
    throw new Error(`${message}: ${JSON.stringify(detail)}`);
  }
}

function previewText(value: unknown): string {
  if (typeof value === "string") return value;
  if (value && typeof value === "object" && !Array.isArray(value) && typeof (value as { text?: unknown }).text === "string") {
    return (value as { text: string }).text;
  }
  return "";
}

function taskDisplayPrompt(task: JsonRecord, preview = false): string {
  if (preview) {
    const previewValue = previewText(task.displayPromptPreview || task.basePromptPreview || task.promptPreview);
    if (previewValue.length > 0) return previewValue;
  }
  const displayPrompt = String(task.displayPrompt || "");
  if (displayPrompt.length > 0) return displayPrompt;
  return String(task.prompt || "");
}

function taskBasePromptText(task: JsonRecord): string {
  const basePrompt = String(task.basePrompt || "");
  return basePrompt.length > 0 ? basePrompt : taskDisplayPrompt(task);
}

function buildLongPrompt(marker: string): string {
  const filler = Array.from(
    { length: 76 },
    (_, index) => `long-prompt-line-${String(index + 1).padStart(2, "0")} ${"abcdefghijklmnopqrstuvwxyz0123456789".repeat(2)}`,
  ).join("\n");
  return [
    "Code Queue long prompt observation contract",
    "",
    filler,
    "",
    "验收标准：",
    `所有原始 prompt 观察层必须保留这个唯一 tail marker: ${marker}`,
  ].join("\n");
}

export function runCodeQueuePromptObservationContract(): JsonRecord {
  const marker = `CODE_QUEUE_PROMPT_OBSERVATION_TAIL_${Date.now()}`;
  const prompt = buildLongPrompt(marker);
  assertCondition(prompt.length > 2500, "long prompt fixture must exceed 2500 chars", { promptChars: prompt.length });

  const task = { prompt, basePrompt: prompt };
  const createTask = codeQueuePromptResponseFields(task, { lite: false, userPromptForDisplay: (value) => value });
  const overviewTask = codeQueuePromptResponseFields(task, { lite: true, userPromptForDisplay: (value) => value });
  const metaTask: JsonRecord = {
    ...codeQueuePromptResponseFields(task, { lite: false, userPromptForDisplay: (value) => value }),
    initialPrompt: prompt,
  };
  const frontendCardPrompt = taskDisplayPrompt(overviewTask, true);
  const frontendFullPrompt = taskBasePromptText(metaTask);
  const rawFields = [
    createTask.prompt,
    createTask.basePrompt,
    createTask.displayPrompt,
    overviewTask.prompt,
    overviewTask.basePrompt,
    overviewTask.displayPrompt,
    metaTask.prompt,
    metaTask.basePrompt,
    metaTask.displayPrompt,
    metaTask.initialPrompt,
    frontendFullPrompt,
  ].map((value) => String(value || ""));
  const previews = [
    createTask.promptPreview,
    createTask.basePromptPreview,
    createTask.displayPromptPreview,
    overviewTask.promptPreview,
    overviewTask.basePromptPreview,
    overviewTask.displayPromptPreview,
  ] as JsonRecord[];

  assertCondition(rawFields.every((value) => value.includes(marker)), "raw prompt fields must include tail marker", {
    marker,
    lengths: rawFields.map((value) => value.length),
  });
  assertCondition(rawFields.every((value) => !value.includes("...<truncated>")), "raw prompt fields must not contain truncation marker");
  assertCondition(previews.every((value) => typeof value?.text === "string" && typeof value?.chars === "number" && typeof value?.truncated === "boolean"), "preview fields must be explicit metadata objects");
  assertCondition(previews.some((value) => value.truncated === true && String(value.text || "").includes("...<truncated>")), "preview fields may truncate explicitly");
  assertCondition(!frontendCardPrompt.includes(marker) && frontendCardPrompt.includes("...<truncated>"), "frontend card summary should use explicit preview text", { frontendCardChars: frontendCardPrompt.length });
  assertCondition(frontendFullPrompt.includes(marker), "frontend full prompt expansion source must include tail marker", { frontendFullChars: frontendFullPrompt.length });

  return {
    ok: true,
    marker,
    promptChars: prompt.length,
    createPromptChars: String(createTask.prompt || "").length,
    overviewPromptChars: String(overviewTask.prompt || "").length,
    metaDisplayPromptChars: String(metaTask.displayPrompt || "").length,
    frontendCardChars: frontendCardPrompt.length,
    frontendFullChars: frontendFullPrompt.length,
    previewTruncated: previews.some((value) => value.truncated === true),
  };
}

if (import.meta.main) {
  process.stdout.write(`${JSON.stringify(runCodeQueuePromptObservationContract(), null, 2)}\n`);
}
