// SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-25-p0-web-probe-sentinel.
// Responsibility: Bounded CLI rendering for the observe wrapper contract.

export function renderWebObserveWrapperContract(value: Record<string, unknown>): string[] {
  const wrapper = nullableRecord(value.wrapper);
  if (wrapper === null) return [];
  const cli = record(wrapper.cli);
  const artifacts = record(wrapper.artifacts);
  const invariants = record(wrapper.invariants);
  return [
    "Wrapper contract:",
    webObserveTable(["SPEC", "MODE", "VERB", "RUNNER", "ANALYZER", "STATE_DIR"], [[
      webObserveShort(webObserveText(wrapper.specRef), 56),
      wrapper.mode,
      wrapper.action,
      invariants.reusesExistingObserveRunner === true && invariants.createsSecondPlaywrightRunner === false ? "existing" : "blocked",
      invariants.reusesExistingObserveAnalyzer === true && invariants.createsSecondAnalyzer === false ? "existing" : "blocked",
      webObserveShort(webObserveText(artifacts.stateDir), 88),
    ]]),
    `  cli: ${webObserveShort(webObserveText(cli.commandShape), 140)}`,
    "",
  ];
}

function webObserveTable(headers: string[], rows: unknown[][]): string {
  const stringRows = rows.map((row) => headers.map((_, index) => webObserveCell(row[index])));
  const widths = headers.map((header, index) => Math.max(header.length, ...stringRows.map((row) => row[index]?.length ?? 0)));
  const renderRow = (row: string[]) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join("  ").trimEnd();
  return [renderRow(headers), ...stringRows.map(renderRow)].join("\n");
}

function webObserveCell(value: unknown, maxLength = 96): string {
  if (value === null || value === undefined) return "-";
  const text = typeof value === "string" ? value : String(value);
  const compact = text.replace(/\s+/gu, " ").trim();
  if (compact.length === 0) return "-";
  if (compact.length <= maxLength) return compact;
  return `${compact.slice(0, Math.max(1, maxLength - 1))}...`;
}

function webObserveText(value: unknown): string {
  if (value === null || value === undefined || value === "") return "-";
  if (typeof value === "string") return value;
  if (typeof value === "number" || typeof value === "boolean") return String(value);
  return JSON.stringify(value);
}

function webObserveShort(value: string, maxLength: number): string {
  if (value.length <= maxLength) return value;
  if (maxLength <= 1) return value.slice(0, maxLength);
  return `${value.slice(0, maxLength - 1)}~`;
}

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

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