function assert(condition: unknown, message = "assertion failed"): void {
  if (!condition) throw new Error(message);
}

function count(markup: string, pattern: RegExp): number {
  return markup.match(pattern)?.length ?? 0;
}

import { renderToStaticMarkup } from "react-dom/server";
import ExplorerTree from "../src/components/ExplorerTree";
import IconButton from "../src/components/IconButton";

type TestNode = {
  id: string;
  label: string;
  children: TestNode[];
};

function noop() {}

const alpha: TestNode = { id: "alpha", label: "Alpha", children: [] };
const beta: TestNode = { id: "beta", label: "Beta", children: [] };
alpha.children.push(beta);
beta.children.push(alpha);

const markup = renderToStaticMarkup(
  <ExplorerTree
    nodes={[alpha, alpha]}
    getNodeId={(node) => node.id}
    getNodeLabel={(node) => node.label}
    getNodeChildren={(node) => node.children}
    activeId="beta"
    collapsible={false}
    onOpen={noop}
    renderNodeContent={(node) => <span>{`node-${node.id}`}</span>}
    renderNodeActions={(node) => (
      <IconButton label={`Add below ${node.label}`} icon={<span>+</span>} onClick={noop} />
    )}
  />
);

assert(markup.includes("node-alpha"), "the root node is rendered");
assert(markup.includes("node-beta"), "non-collapsible trees render descendants without expansion state");
assert(count(markup, /node-alpha/g) === 1, "a cycle does not render an ancestor again");
assert(count(markup, /node-beta/g) === 1, "duplicate paths do not duplicate descendants");
assert(count(markup, /explorer-tree-toggle-static/g) === 2, "non-collapsible nodes render static tree affordances");
assert(!markup.includes('<button type="button" class="explorer-tree-toggle'), "non-collapsible nodes do not expose dead toggle buttons");
assert(markup.includes("explorer-tree-node-wrap file-tree-node-wrap has-actions"), "rows reserve a sibling action column only when used");
assert(markup.includes('class="explorer-tree-actions" role="group"'), "node actions expose group semantics");
assert(markup.includes('aria-label="Add below Alpha"'), "node action controls retain accessible labels");
assert(
  /node-alpha<\/span><\/button><div class="explorer-tree-actions"/.test(markup),
  "node actions are siblings of the node button instead of nested interactive content"
);
assert(markup.includes('aria-current="true"'), "the active node is exposed to assistive technology");
