// SPEC: GH-1548/GH-1560 archived Gitea Actions POC.
// Responsibility: read-only historical plan/status for the retired Gitea Actions POC.
import { existsSync, readFileSync } from "node:fs";
import { isAbsolute } from "node:path";
import { rootPath, type UniDeskConfig } from "./config";
import { renderMachine } from "./cicd-render";
import type { RenderedCliResult } from "./output";

const DEFAULT_CONFIG_PATH = "config/cicd-gitea-actions-poc.yaml";

type OutputMode = "text" | "json" | "yaml";
type Action = "plan" | "status" | "help";

interface Options {
  action: Action;
  configPath: string;
  output: OutputMode;
  targetId: string | null;
}

interface LoadedPoc {
  configPath: string;
  root: Record<string, unknown>;
  spec: Record<string, unknown>;
  errors: string[];
  warnings: string[];
}

export function cicdGiteaActionsPocHelp(): unknown {
  return {
    command: "cicd gitea-actions-poc plan|status",
    archived: true,
    replacement: "bun scripts/cli.ts platform-infra pipelines-as-code status --target JD01",
    output: "text by default; use --json, --raw, or -o json|yaml for machine output",
    usage: [
      "bun scripts/cli.ts cicd gitea-actions-poc plan",
      "bun scripts/cli.ts cicd gitea-actions-poc status",
      "bun scripts/cli.ts cicd gitea-actions-poc plan --target agentrun-jd01-v02",
    ],
    config: DEFAULT_CONFIG_PATH,
    issue: "https://github.com/pikasTech/unidesk/issues/1560",
    description: "Archived read-only POC. JD01 production CI/CD uses Gitea mirror -> Pipelines-as-Code -> Tekton -> Argo/k8s runtime; do not use Gitea Actions or act_runner as a fallback.",
  };
}

export async function runGiteaActionsPocCommand(_config: UniDeskConfig | null, args: string[], alias = "gitea-actions-poc"): Promise<RenderedCliResult> {
  const options = parseOptions(args);
  const command = `cicd ${alias}${options.action === "help" ? "" : ` ${options.action}`}`;
  if (options.action === "help") return renderMachine(command, cicdGiteaActionsPocHelp(), options.output === "yaml" ? "yaml" : "json");
  const loaded = loadPoc(options.configPath);
  const payload = options.action === "plan" ? buildPlan(loaded, options) : buildStatus(loaded, options);
  if (options.output === "json") return renderMachine(command, payload, "json", payload.ok !== false);
  if (options.output === "yaml") return renderMachine(command, payload, "yaml", payload.ok !== false);
  return {
    ok: payload.ok !== false,
    command,
    renderedText: options.action === "plan" ? renderPlanHuman(payload) : renderStatusHuman(payload),
    contentType: "text/plain",
  };
}

function parseOptions(args: string[]): Options {
  const actionToken = args[0];
  const action: Action = actionToken === undefined || isHelpToken(actionToken) ? "help" : parseAction(actionToken);
  const options: Options = {
    action,
    configPath: DEFAULT_CONFIG_PATH,
    output: "text",
    targetId: null,
  };
  for (let index = action === "help" ? 0 : 1; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === undefined || isHelpToken(arg)) {
      options.action = "help";
      continue;
    }
    if (arg === "--json" || arg === "--raw") {
      options.output = "json";
      continue;
    }
    if (arg === "-o" || arg === "--output") {
      const value = args[index + 1];
      if (value === undefined) throw new Error(`${arg} requires text, json, or yaml`);
      options.output = parseOutput(value, arg);
      index += 1;
      continue;
    }
    if (arg.startsWith("-o=")) {
      options.output = parseOutput(arg.slice(3), "-o");
      continue;
    }
    if (arg.startsWith("--output=")) {
      options.output = parseOutput(arg.slice("--output=".length), "--output");
      continue;
    }
    if (arg === "--config") {
      const value = args[index + 1];
      if (value === undefined || value.length === 0) throw new Error("--config requires a path");
      options.configPath = value;
      index += 1;
      continue;
    }
    if (arg.startsWith("--config=")) {
      options.configPath = arg.slice("--config=".length);
      continue;
    }
    if (arg === "--target") {
      const value = args[index + 1];
      if (value === undefined || value.length === 0) throw new Error("--target requires a target id");
      options.targetId = value;
      index += 1;
      continue;
    }
    if (arg.startsWith("--target=")) {
      options.targetId = arg.slice("--target=".length);
      continue;
    }
    if (arg === "--confirm") throw new Error("cicd gitea-actions-poc is read-only in GH-1548 P1/P2; --confirm is not accepted");
    if (arg === "--dry-run" || arg === "--all") continue;
    throw new Error(`unsupported cicd gitea-actions-poc option: ${arg}`);
  }
  return options;
}

function parseAction(value: string): Action {
  if (value === "plan" || value === "status") return value;
  if (isHelpToken(value)) return "help";
  if (value === "apply" || value === "run-once" || value === "trigger-current") {
    throw new Error(`cicd gitea-actions-poc ${value} is intentionally unavailable; GH-1548 first stage is read-only plan/status`);
  }
  throw new Error("cicd gitea-actions-poc usage: cicd gitea-actions-poc plan|status [--target <id>] [--config <path>]");
}

function parseOutput(value: string, flag: string): OutputMode {
  if (value === "text" || value === "json" || value === "yaml") return value;
  throw new Error(`${flag} must be text, json, or yaml`);
}

function isHelpToken(value: string): boolean {
  return value === "help" || value === "--help" || value === "-h";
}

function loadPoc(configPath: string): LoadedPoc {
  const absolutePath = isAbsolute(configPath) ? configPath : rootPath(configPath);
  if (!existsSync(absolutePath)) throw new Error(`${configPath} does not exist`);
  const root = record(Bun.YAML.parse(readFileSync(absolutePath, "utf8")), configPath);
  const spec = record(root.spec, `${configPath}.spec`);
  const errors: string[] = [];
  const warnings: string[] = [];
  validateRoot(root, spec, configPath, errors, warnings);
  return { configPath, root, spec, errors, warnings };
}

function validateRoot(root: Record<string, unknown>, spec: Record<string, unknown>, configPath: string, errors: string[], warnings: string[]): void {
  if (stringOrNull(root.kind) !== "CicdGiteaActionsPoc") errors.push(`${configPath}.kind must be CicdGiteaActionsPoc`);
  const scope = optionalRecord(spec.scope);
  if (scope?.productionFollowerReplacement !== false) errors.push(`${configPath}.spec.scope.productionFollowerReplacement must be false for first-stage POC`);
  if (scope?.rolloutEnabled !== false) errors.push(`${configPath}.spec.scope.rolloutEnabled must be false for first-stage POC`);
  const runtimePlane = optionalRecord(spec.runtimePlane);
  if (runtimePlane?.dockerAllowed !== false) errors.push(`${configPath}.spec.runtimePlane.dockerAllowed must be false`);
  if (runtimePlane?.buildAllowed !== false) errors.push(`${configPath}.spec.runtimePlane.buildAllowed must be false`);
  if (runtimePlane?.dockerSocketAllowed !== false) errors.push(`${configPath}.spec.runtimePlane.dockerSocketAllowed must be false`);
  const buildPlane = optionalRecord(spec.buildPlane);
  if (buildPlane?.dockerAllowed !== true) errors.push(`${configPath}.spec.buildPlane.dockerAllowed must be true for the controlled builder POC`);
  if (buildPlane?.forbidMasterServer !== true) errors.push(`${configPath}.spec.buildPlane.forbidMasterServer must be true`);
  if (buildPlane?.forbidRuntimeNode !== true) errors.push(`${configPath}.spec.buildPlane.forbidRuntimeNode must be true`);
  const reuse = optionalRecord(spec.reuse);
  if (reuse?.p0NoRegression !== true) errors.push(`${configPath}.spec.reuse.p0NoRegression must be true`);
  if (reuse?.ciConsumptionRequired !== true) errors.push(`${configPath}.spec.reuse.ciConsumptionRequired must be true`);
  const decisions = stringArray(reuse?.requiredDecisions);
  if (!decisions.includes("skipImageBuild")) errors.push(`${configPath}.spec.reuse.requiredDecisions must include skipImageBuild`);
  if (!decisions.includes("reuseEnvImage")) errors.push(`${configPath}.spec.reuse.requiredDecisions must include reuseEnvImage`);
  const targets = arrayRecords(spec.targets);
  if (targets.length === 0) errors.push(`${configPath}.spec.targets must declare at least one POC target`);
  const enabledTargets = targets.filter((target) => target.enabled !== false);
  if (enabledTargets.length === 0) warnings.push(`${configPath}.spec.targets has no enabled target`);
  if (arrayRecords(spec.componentSurvey).length === 0) warnings.push(`${configPath}.spec.componentSurvey is empty; component maturity evidence will be invisible`);
}

function buildPlan(loaded: LoadedPoc, options: Options): Record<string, unknown> {
  const targets = selectedTargets(loaded, options);
  const scope = optionalRecord(loaded.spec.scope);
  return {
    ok: loaded.errors.length === 0 && targets.errors.length === 0,
    action: "plan",
    configPath: loaded.configPath,
    issue: stringOrNull(optionalRecord(loaded.root.metadata)?.issue),
    specRef: stringOrNull(optionalRecord(loaded.root.metadata)?.specRef),
    phase: stringOrNull(scope?.phase),
    rolloutEnabled: scope?.rolloutEnabled === true,
    productionFollowerReplacement: scope?.productionFollowerReplacement === true,
    migration: compactMigration(optionalRecord(loaded.spec.migration)),
    sourceAuthority: compactSourceAuthority(optionalRecord(loaded.spec.sourceAuthority)),
    planes: [
      compactRuntimePlane(optionalRecord(loaded.spec.runtimePlane)),
      compactBuildPlane(optionalRecord(loaded.spec.buildPlane)),
    ],
    reuse: compactReuse(optionalRecord(loaded.spec.reuse)),
    targets: targets.items.map(compactTarget),
    stages: arrayRecords(loaded.spec.stages).map(compactStage),
    componentSurvey: arrayRecords(loaded.spec.componentSurvey).map(compactComponent),
    statusProjection: compactStatusProjection(optionalRecord(loaded.spec.statusProjection)),
    budgets: loaded.spec.budgets ?? null,
    errors: [...loaded.errors, ...targets.errors],
    warnings: loaded.warnings,
    valuesRedacted: true,
    next: nextCommands(loaded, targets.items[0]),
  };
}

function buildStatus(loaded: LoadedPoc, options: Options): Record<string, unknown> {
  const plan = buildPlan(loaded, options);
  const targets = arrayRecords(plan.targets);
  return {
    ...plan,
    action: "status",
    statusSource: "config-only",
    statusMode: "declared-poc-not-applied",
    checks: targets.map((target) => ({
      target: target.id,
      source: "declared",
      giteaMirror: "not-applied",
      actionsRun: "not-applied",
      tekton: "existing-component",
      builderPlane: "declared-controlled-docker",
      argo: "existing-component",
      runtimePlane: "zero-docker-required",
      reuse: "p0-required-not-yet-proven-in-poc",
    })),
  };
}

function selectedTargets(loaded: LoadedPoc, options: Options): { items: Record<string, unknown>[]; errors: string[] } {
  const targets = arrayRecords(loaded.spec.targets);
  if (options.targetId === null) return { items: targets, errors: [] };
  const selected = targets.filter((target) => stringOrNull(target.id) === options.targetId);
  return selected.length > 0 ? { items: selected, errors: [] } : { items: [], errors: [`target ${options.targetId} not found in ${loaded.configPath}`] };
}

function compactSourceAuthority(value: Record<string, unknown> | null): Record<string, unknown> {
  const mirror = optionalRecord(value?.giteaMirror);
  return {
    mode: stringOrNull(value?.mode),
    allowMutableBranchAsCiSource: value?.allowMutableBranchAsCiSource === true,
    allowHostWorktree: value?.allowHostWorktree === true,
    existingMirrorRef: stringOrNull(value?.existingMirrorRef),
    giteaMirrorEnabledForPoc: mirror?.enabledForPoc === true,
    giteaInternalBaseUrl: stringOrNull(mirror?.internalBaseUrl),
    snapshotRefPrefix: stringOrNull(mirror?.snapshotRefPrefix),
    repositories: arrayRecords(mirror?.repositories).map((repo) => `${repo.repository ?? "-"}@${repo.upstreamBranch ?? "-"}`),
  };
}

function compactMigration(value: Record<string, unknown> | null): Record<string, unknown> {
  const branchFollower = optionalRecord(value?.branchFollower);
  return {
    issue: stringOrNull(value?.issue),
    primaryEntrypoint: stringOrNull(value?.primaryEntrypoint),
    replacementTarget: stringOrNull(value?.replacementTarget),
    branchFollower: {
      status: stringOrNull(branchFollower?.status),
      mode: stringOrNull(branchFollower?.mode),
      reason: stringOrNull(branchFollower?.reason),
      allowedDuringMigration: stringArray(branchFollower?.allowedDuringMigration),
      frozenCapabilities: stringArray(branchFollower?.frozenCapabilities),
      finalDisposition: stringOrNull(branchFollower?.finalDisposition),
    },
  };
}

function compactRuntimePlane(value: Record<string, unknown> | null): Record<string, unknown> {
  return {
    plane: "runtime",
    dockerAllowed: value?.dockerAllowed === true,
    buildAllowed: value?.buildAllowed === true,
    dockerSocketAllowed: value?.dockerSocketAllowed === true,
    hostWorktreeAllowed: value?.hostWorktreeAllowed === true,
    sourceAuthority: stringOrNull(value?.sourceAuthority),
    deployMode: stringOrNull(value?.deployMode),
    statusAuthority: stringArray(value?.statusAuthority),
  };
}

function compactBuildPlane(value: Record<string, unknown> | null): Record<string, unknown> {
  return {
    plane: "ci-build",
    dockerAllowed: value?.dockerAllowed === true,
    buildAllowed: value?.buildAllowed === true,
    dockerScope: stringOrNull(value?.dockerScope),
    mode: stringOrNull(value?.mode),
    engineCandidates: stringArray(value?.engineCandidates),
    selectedEngineForPoc: stringOrNull(value?.selectedEngineForPoc),
    forbidMasterServer: value?.forbidMasterServer === true,
    forbidRuntimeNode: value?.forbidRuntimeNode === true,
    endpointRef: stringOrNull(optionalRecord(value?.endpoint)?.ref),
    registryRef: stringOrNull(optionalRecord(value?.registry)?.ref),
    provenanceRequired: optionalRecord(value?.provenance)?.required === true,
    provenanceFields: stringArray(optionalRecord(value?.provenance)?.fields),
  };
}

function compactReuse(value: Record<string, unknown> | null): Record<string, unknown> {
  return {
    p0NoRegression: value?.p0NoRegression === true,
    sourceTruth: stringOrNull(value?.sourceTruth),
    sourceRead: stringOrNull(value?.sourceRead),
    existingParser: stringOrNull(value?.existingParser),
    existingAgentRunPlanner: stringOrNull(value?.existingAgentRunPlanner),
    ciConsumptionRequired: value?.ciConsumptionRequired === true,
    requiredDecisions: stringArray(value?.requiredDecisions),
    requiredArtifacts: stringArray(value?.requiredArtifacts),
    noRegressionChecks: stringArray(value?.noRegressionChecks),
  };
}

function compactTarget(value: Record<string, unknown>): Record<string, unknown> {
  return {
    id: stringOrNull(value.id),
    enabled: value.enabled !== false,
    repository: stringOrNull(value.repository),
    branch: stringOrNull(value.branch),
    node: stringOrNull(value.node),
    lane: stringOrNull(value.lane),
    baselineSeconds: optionalRecord(value.baseline)?.currentBranchFollowerSeconds ?? null,
    budgetRef: stringOrNull(optionalRecord(value.baseline)?.budgetRef),
    snapshotRef: stringOrNull(optionalRecord(value.source)?.snapshotRef),
    mirrorReadUrlRef: stringOrNull(optionalRecord(value.source)?.currentMirrorReadUrlRef),
    workflowRef: stringOrNull(optionalRecord(value.actions)?.workflowRef),
    pipelineRef: stringOrNull(optionalRecord(value.tekton)?.pipelineRef),
    argoApplicationRef: stringOrNull(optionalRecord(value.argo)?.applicationRef),
    runtimeNamespaceRef: stringOrNull(optionalRecord(value.runtime)?.namespaceRef),
    workload: stringOrNull(optionalRecord(value.runtime)?.workload),
    healthPath: stringOrNull(optionalRecord(value.closeout)?.healthPath),
    requiredEvidence: stringArray(optionalRecord(value.closeout)?.requiredEvidence),
  };
}

function compactStage(value: Record<string, unknown>): Record<string, unknown> {
  return {
    id: stringOrNull(value.id),
    owner: stringOrNull(value.owner),
    statusAuthority: stringOrNull(value.statusAuthority),
    output: stringOrNull(value.output),
  };
}

function compactComponent(value: Record<string, unknown>): Record<string, unknown> {
  return {
    component: stringOrNull(value.component),
    role: stringOrNull(value.role),
    maturity: stringOrNull(value.maturity),
    directReuse: stringOrNull(value.directReuse),
    docs: stringOrNull(value.docs),
    risk: stringOrNull(value.risk),
  };
}

function compactStatusProjection(value: Record<string, unknown> | null): Record<string, unknown> {
  return {
    mode: stringOrNull(value?.mode),
    defaultOutputMustNotDump: value?.defaultOutputMustNotDump === true,
    requiredFields: stringArray(value?.requiredFields),
    drillDown: optionalRecord(value?.drillDown) ?? {},
  };
}

function nextCommands(loaded: LoadedPoc, firstTarget: Record<string, unknown> | undefined): Record<string, unknown> {
  const declared = optionalRecord(loaded.spec.next);
  const targetId = stringOrNull(firstTarget?.id) ?? "agentrun-jd01-v02";
  return {
    plan: stringOrNull(declared?.plan) ?? "bun scripts/cli.ts cicd gitea-actions-poc plan",
    status: stringOrNull(declared?.status) ?? "bun scripts/cli.ts cicd gitea-actions-poc status",
    existingFollowerStatus: stringOrNull(declared?.existingFollowerStatus) ?? `bun scripts/cli.ts cicd branch-follower status --follower ${targetId}`,
    pocIssue: stringOrNull(declared?.pocIssue),
  };
}

function renderPlanHuman(payload: Record<string, unknown>): string {
  const next = optionalRecord(payload.next);
  const planes = arrayRecords(payload.planes);
  const reuse = optionalRecord(payload.reuse);
  const migration = optionalRecord(payload.migration);
  const branchFollower = optionalRecord(migration?.branchFollower);
  const statusProjection = optionalRecord(payload.statusProjection);
  const errors = stringArray(payload.errors);
  const warnings = stringArray(payload.warnings);
  return [
    `CI/CD GITEA-ACTIONS POC PLAN (${payload.ok === false ? "blocked" : "ok"})`,
    "",
    "ARCHIVE NOTICE",
    "This is historical GH-1548 POC material. Current JD01 CI/CD closeout is platform-infra pipelines-as-code status/history; Gitea Actions and act_runner are not fallback paths.",
    "",
    table(["TARGET", "SOURCE", "NODE/LANE", "BASELINE", "SNAPSHOT", "TEKTON", "ARGO", "RUNTIME"], arrayRecords(payload.targets).map((target) => [
      target.id,
      `${target.repository ?? "-"}@${target.branch ?? "-"}`,
      `${target.node ?? "-"}/${target.lane ?? "-"}`,
      target.baselineSeconds === null ? "-" : `${target.baselineSeconds}s`,
      target.snapshotRef,
      target.pipelineRef,
      target.argoApplicationRef,
      target.workload,
    ])),
    "",
    "SOURCE AUTHORITY",
    sourceAuthorityLine(optionalRecord(payload.sourceAuthority)),
    "",
    "MIGRATION POLICY",
    `replacement=${migration?.replacementTarget ?? "-"} primary=${migration?.primaryEntrypoint ?? "-"} branchFollower=${branchFollower?.status ?? "-"}:${branchFollower?.mode ?? "-"}`,
    `frozen=${stringArray(branchFollower?.frozenCapabilities).join(",") || "-"}`,
    "",
    table(["PLANE", "DOCKER", "BUILDS", "MODE", "ENGINE", "MASTER", "RUNTIME_NODE", "AUTHORITY"], planes.map((plane) => [
      plane.plane,
      boolText(plane.dockerAllowed),
      boolText(plane.buildAllowed),
      plane.mode ?? plane.deployMode ?? "-",
      plane.selectedEngineForPoc ?? "-",
      plane.forbidMasterServer === true ? "forbidden" : "-",
      plane.forbidRuntimeNode === true ? "forbidden" : "-",
      plane.sourceAuthority ?? plane.endpointRef ?? "-",
    ])),
    "",
    "REUSE CONTRACT",
    `source=${reuse?.sourceTruth ?? "-"} p0=${boolText(reuse?.p0NoRegression)} ciConsumption=${boolText(reuse?.ciConsumptionRequired)} decisions=${stringArray(reuse?.requiredDecisions).join(",") || "-"}`,
    `artifacts=${stringArray(reuse?.requiredArtifacts).join(",") || "-"}`,
    "",
    table(["STAGE", "OWNER", "STATUS_AUTHORITY", "OUTPUT"], arrayRecords(payload.stages).map((stage) => [stage.id, stage.owner, stage.statusAuthority, stage.output])),
    "",
    table(["COMPONENT", "ROLE", "MATURITY", "DIRECT_REUSE", "RISK"], arrayRecords(payload.componentSurvey).map((component) => [component.component, component.role, component.maturity, component.directReuse, component.risk])),
    "",
    "STATUS FIELDS",
    stringArray(statusProjection?.requiredFields).join(", ") || "-",
    warnings.length === 0 ? "" : `\nWARNINGS\n${warnings.map((item) => `- ${item}`).join("\n")}`,
    errors.length === 0 ? "" : `\nERRORS\n${errors.map((item) => `- ${item}`).join("\n")}`,
    "",
    "NEXT",
    `pac-status: bun scripts/cli.ts platform-infra pipelines-as-code status --target JD01`,
    `pac-history: bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 --limit 10`,
    `archived-status: ${next?.status ?? "-"}`,
    `legacy-follower: ${next?.existingFollowerStatus ?? "-"}`,
    `issue: ${next?.pocIssue ?? payload.issue ?? "-"}`,
    "",
  ].filter((line) => line !== "").join("\n");
}

function renderStatusHuman(payload: Record<string, unknown>): string {
  const next = optionalRecord(payload.next);
  const migration = optionalRecord(payload.migration);
  const branchFollower = optionalRecord(migration?.branchFollower);
  const errors = stringArray(payload.errors);
  return [
    `CI/CD GITEA-ACTIONS POC STATUS (${payload.ok === false ? "blocked" : "declared-only"})`,
    "",
    "ARCHIVE NOTICE",
    "This command reads an archived POC spec only. Use platform-infra pipelines-as-code status/history for current JD01 CI/CD evidence.",
    "",
    `statusSource=${payload.statusSource ?? "-"} mode=${payload.statusMode ?? "-"}`,
    `replacement=${migration?.replacementTarget ?? "-"} branchFollower=${branchFollower?.status ?? "-"}:${branchFollower?.mode ?? "-"}`,
    "",
    table(["TARGET", "SOURCE", "GITEA", "ACTIONS", "TEKTON", "BUILDER", "ARGO", "RUNTIME", "REUSE"], arrayRecords(payload.checks).map((check) => [
      check.target,
      check.source,
      check.giteaMirror,
      check.actionsRun,
      check.tekton,
      check.builderPlane,
      check.argo,
      check.runtimePlane,
      check.reuse,
    ])),
    errors.length === 0 ? "" : `\nERRORS\n${errors.map((item) => `- ${item}`).join("\n")}`,
    "",
    "NEXT",
    `pac-status: bun scripts/cli.ts platform-infra pipelines-as-code status --target JD01`,
    `pac-history: bun scripts/cli.ts platform-infra pipelines-as-code history --target JD01 --limit 10`,
    `archived-plan: ${next?.plan ?? "-"}`,
    `legacy-follower: ${next?.existingFollowerStatus ?? "-"}`,
    "",
  ].filter((line) => line !== "").join("\n");
}

function sourceAuthorityLine(value: Record<string, unknown> | null): string {
  return [
    `mode=${value?.mode ?? "-"}`,
    `mutableBranch=${boolText(value?.allowMutableBranchAsCiSource)}`,
    `hostWorktree=${boolText(value?.allowHostWorktree)}`,
    `giteaEnabled=${boolText(value?.giteaMirrorEnabledForPoc)}`,
    `snapshot=${value?.snapshotRefPrefix ?? "-"}`,
  ].join(" ");
}

function record(value: unknown, path: string): Record<string, unknown> {
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${path} must be a YAML object`);
  return value as Record<string, unknown>;
}

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

function arrayRecords(value: unknown): Record<string, unknown>[] {
  return Array.isArray(value) ? value.filter((item): item is Record<string, unknown> => typeof item === "object" && item !== null && !Array.isArray(item)) : [];
}

function stringArray(value: unknown): string[] {
  return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string" && item.length > 0) : [];
}

function stringOrNull(value: unknown): string | null {
  return typeof value === "string" && value.length > 0 ? value : null;
}

function boolText(value: unknown): string {
  return value === true ? "true" : value === false ? "false" : "-";
}

function table(headers: readonly string[], rows: readonly (readonly unknown[])[]): string {
  const normalized = rows.map((row) => headers.map((_, index) => cell(row[index])));
  const widths = headers.map((header, index) => Math.max(header.length, ...normalized.map((row) => row[index]?.length ?? 0)));
  const format = (row: readonly string[]) => row.map((value, index) => value.padEnd(widths[index] ?? 0)).join("  ").trimEnd();
  return [format(headers), format(headers.map((header) => "-".repeat(header.length))), ...normalized.map(format)].join("\n");
}

function cell(value: unknown): string {
  if (value === null || value === undefined || value === "") return "-";
  const text = String(value).replace(/\s+/gu, " ");
  return text.length > 96 ? `${text.slice(0, 93)}...` : text;
}
