import { SYNTAX_PROFILE } from "../version";
import type { RegexExecutionResult } from "../regex/model/match";
import type { RegexSyntaxResult } from "../regex/model/syntax";
import type {
  RegexEngineCapabilities,
  RegexFlavourId,
} from "../regex/model/flavour";

const FLAVOUR_LABELS: Readonly<Record<RegexFlavourId, string>> = {
  ecmascript: "JavaScript (ECMAScript)",
  pcre2: "PCRE2",
  pcre: "PCRE",
  php: "PHP preg / PCRE2",
  perl: "Perl (legacy WebPerl)",
  python: "Python re",
  ruby: "Ruby Regexp",
  cpp: "C++ std::regex",
  go: "Go regexp",
  rust: "Rust regex",
  dotnet: ".NET Regex",
  java: "Java Pattern",
  scala: "Scala Regex / Java compatibility",
};

function capability(
  capabilities: RegexEngineCapabilities | undefined,
  key: keyof RegexEngineCapabilities,
  unavailableDetail?: string,
): string {
  if (!capabilities) return "Awaiting first engine result";
  if (capabilities[key]) return "Available";
  return unavailableDetail
    ? `Unavailable — ${unavailableDetail}`
    : "Unavailable";
}

function offsetLabel(
  unit: RegexExecutionResult["engine"]["offsetUnit"] | undefined,
): string {
  switch (unit) {
    case "utf16":
      return "UTF-16 code units";
    case "code-point":
      return "Unicode code points";
    case "utf8-byte":
      return "UTF-8 bytes";
    case "byte":
      return "Bytes";
    default:
      return "Awaiting first engine result";
  }
}

export function CapabilityPanel({
  syntax,
  execution,
  onClose,
}: {
  readonly syntax?: RegexSyntaxResult;
  readonly execution?: RegexExecutionResult;
  readonly onClose?: () => void;
}) {
  const capabilities = execution?.engine.capabilities;
  const activeFlavour =
    execution?.engine.flavour ?? syntax?.root.support.flavour;
  const activeFlavourLabel = activeFlavour
    ? FLAVOUR_LABELS[activeFlavour]
    : undefined;
  const rows = [
    [
      "Flavour",
      execution?.engine.flavour ??
        syntax?.root.support.flavour ??
        "Awaiting flavour workers",
    ],
    [
      "Syntax provider",
      syntax
        ? `${syntax.provider.id} ${syntax.provider.version}`
        : "Awaiting syntax worker result",
    ],
    ["Syntax profile", SYNTAX_PROFILE],
    [
      "Provider coverage",
      syntax
        ? `${syntax.coverage.status}: ${syntax.coverage.summary}`
        : "Awaiting syntax worker result",
    ],
    [
      "Execution engine",
      execution?.engine.engineName ?? "Awaiting first engine result",
    ],
    [
      "Engine version",
      execution?.engine.engineVersion ?? "Shown after first execution",
    ],
    [
      "Runtime version",
      execution?.engine.runtimeVersion ??
        (execution
          ? "Not separately reported by this adapter"
          : "Shown after first execution"),
    ],
    [
      "Adapter version",
      execution?.engine.adapterVersion ?? "Shown after first execution",
    ],
    ["Native offsets", offsetLabel(execution?.engine.offsetUnit)],
    ["Compilation", capability(capabilities, "compilation")],
    ["Matching", capability(capabilities, "matching")],
    ["Replacement", capability(capabilities, "replacement")],
    ["Named captures", capability(capabilities, "namedCaptures")],
    [
      "Capture history",
      capability(
        capabilities,
        "captureHistory",
        "the adapter exposes only the final retained capture",
      ),
    ],
    [
      "Actual execution trace",
      activeFlavour === "pcre2"
        ? capability(
            capabilities,
            "actualTrace",
            "this PCRE2 adapter exposes no bounded automatic-callout trace",
          )
        : activeFlavour
          ? "Unavailable — automatic-callout tracing is implemented only for PCRE2"
          : "Awaiting flavour worker result",
    ],
    ["Benchmark", capability(capabilities, "benchmark")],
    [
      "Static risk analysis",
      activeFlavour === "ecmascript"
        ? "Available — advisory ECMAScript 2025 heuristics"
        : activeFlavourLabel
          ? `Unavailable — ECMAScript heuristics are not applied to ${activeFlavourLabel}`
          : "Awaiting flavour worker result",
    ],
    [
      "Generated cases",
      activeFlavour === "ecmascript"
        ? "Available — deterministic AST candidates, retained only after actual-engine verification"
        : activeFlavourLabel
          ? `Unavailable — the ECMAScript case generator is not applied to ${activeFlavourLabel}`
          : "Awaiting flavour worker result",
    ],
    [
      "Pattern formatting",
      activeFlavour === "ecmascript"
        ? "Available — grammar-backed literal/control escaping with mandatory exact-snapshot validation"
        : activeFlavourLabel
          ? `Unavailable — the ECMAScript formatter is not applied to ${activeFlavourLabel}`
          : "Awaiting flavour worker result",
    ],
    [
      "Code generation",
      activeFlavour === "pcre2"
        ? "Available — reviewed PCRE2 10.47 8-bit C17 target"
        : activeFlavour
          ? "Unavailable — C17 code generation is implemented only for PCRE2"
          : "Awaiting flavour worker result",
    ],
    [
      "Known syntax gaps",
      syntax
        ? syntax.coverage.unsupportedConstructs.length > 0
          ? syntax.coverage.unsupportedConstructs.join("; ")
          : "None reported by the active provider"
        : "Awaiting syntax worker result",
    ],
  ] as const;
  return (
    <section
      className="panel capability-panel"
      aria-labelledby="capability-heading"
    >
      <header className="panel-heading">
        <div>
          <p className="eyebrow">Current provider and adapter metadata</p>
          <h2 id="capability-heading">Capabilities</h2>
        </div>
        <div className="panel-heading-actions">
          <span className="provenance-badge">Community build</span>
          {onClose ? (
            <button
              type="button"
              className="icon-button"
              aria-label="Close capabilities"
              data-dialog-initial-focus
              onClick={onClose}
            >
              ×
            </button>
          ) : null}
        </div>
      </header>
      <dl className="capability-grid">
        {rows.map(([term, value]) => (
          <div key={term}>
            <dt>{term}</dt>
            <dd>{value}</dd>
          </div>
        ))}
      </dl>
      <p className="capability-roadmap">
        Availability is never inferred by substituting one flavour for another.
        Static analysis, generated cases and formatting are ECMAScript-only;
        automatic-callout tracing and reviewed C17 generation are PCRE2-only.
        Every executable profile retains the exact engine identity and
        compatibility boundaries reported by its own worker; partial lexical
        syntax coverage is never presented as a complete grammar.
      </p>
    </section>
  );
}
