// Support-matrix generator: derives human-readable matrix from ADVANCED_SETTINGS × ASSET_CAPABILITIES.
// Regenerate with `pnpm --filter @sdp/issuance matrix:generate`.

import type { AssetCategory, SettingAvailability } from "@sdp/types";
import { ASSET_CAPABILITIES } from "./capabilities";
import { ADVANCED_SETTINGS, SETTING_KEYS, type SettingKey } from "./settings";

export interface SupportMatrixSettingRow {
  key: SettingKey;
  group: string;
  extensions: string[];
  actions: string[];
}

export interface SupportMatrixAvailabilityRow {
  category: AssetCategory;
  type: string;
  baseTemplate: string;
  availability: Record<SettingKey, SettingAvailability>;
}

export interface SupportMatrix {
  settings: SupportMatrixSettingRow[];
  availability: SupportMatrixAvailabilityRow[];
}

// Build structured matrix for markdown rendering and consumption.
export function buildSupportMatrix(): SupportMatrix {
  const settings: SupportMatrixSettingRow[] = SETTING_KEYS.map((key) => {
    const setting = ADVANCED_SETTINGS[key];
    return {
      key,
      group: setting.group,
      extensions: [...setting.extensions],
      actions: [...setting.actions],
    };
  });

  const availability: SupportMatrixAvailabilityRow[] = ASSET_CAPABILITIES.map((capability) => ({
    category: capability.category,
    type: capability.type,
    baseTemplate: capability.baseTemplate,
    availability: Object.fromEntries(
      SETTING_KEYS.map((key) => [key, capability.settings[key]])
    ) as Record<SettingKey, SettingAvailability>,
  }));

  return { settings, availability };
}

const AVAILABILITY_CELL: Record<SettingAvailability, string> = {
  locked: "req",
  recommended: "rec",
  available: "opt",
  unsupported: "—",
};

function row(cells: string[]): string {
  return `| ${cells.join(" | ")} |`;
}

// Render matrix as SUPPORT_MATRIX.md; deterministic for byte-for-byte drift checks.
export function renderSupportMatrixMarkdown(matrix: SupportMatrix = buildSupportMatrix()): string {
  const lines: string[] = [];

  lines.push(
    "<!-- AUTO-GENERATED by `pnpm --filter @sdp/issuance matrix:generate`. Do not edit by hand. -->"
  );
  lines.push("");
  lines.push("# Advanced settings support matrix");
  lines.push("");
  lines.push(
    "Manager-facing advanced settings, the SDP actions and Token-2022 extensions each maps to, " +
      "and which asset types support them. Derived from the capability registry."
  );
  lines.push("");

  // Settings → SDP actions (+ extensions).
  lines.push("## Settings → SDP actions");
  lines.push("");
  lines.push(row(["Setting", "Group", "Extensions", "SDP actions"]));
  lines.push(row(["---", "---", "---", "---"]));
  for (const s of matrix.settings) {
    lines.push(row([s.key, s.group, s.extensions.join(", "), s.actions.join(", ") || "—"]));
  }
  lines.push("");

  // Availability by asset type.
  lines.push("## Availability by asset type");
  lines.push("");
  lines.push(
    "Legend: `req` = locked (forced on) · `rec` = recommended (default on) · " +
      "`opt` = available (opt-in) · `—` = unsupported."
  );
  lines.push("");
  lines.push(row(["Asset type", "Template", ...SETTING_KEYS]));
  lines.push(row(["---", "---", ...SETTING_KEYS.map(() => "---")]));
  for (const a of matrix.availability) {
    lines.push(
      row([
        `${a.category}/${a.type}`,
        a.baseTemplate,
        ...SETTING_KEYS.map((key) => AVAILABILITY_CELL[a.availability[key]]),
      ])
    );
  }
  lines.push("");

  // Unsupported gaps, listed explicitly.
  lines.push("## Unsupported gaps");
  lines.push("");
  for (const a of matrix.availability) {
    const unsupported = SETTING_KEYS.filter((key) => a.availability[key] === "unsupported");
    lines.push(
      `- \`${a.category}/${a.type}\`: ${unsupported.length ? unsupported.join(", ") : "none"}`
    );
  }
  lines.push("");

  return lines.join("\n");
}
