"use client";
import * as React from 'react';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { jsxs, jsx } from 'react/jsx-runtime';

function cn(...inputs) {
  return twMerge(clsx(inputs));
}
function Arc({
  nodes,
  edges,
  width = 720,
  height = 360,
  nodeRadius = 5,
  onEdgeHover,
  onNodeClick,
  className,
  ...rest
}) {
  const laidOut = React.useMemo(() => layout(nodes, edges, width, height), [nodes, edges, width, height]);
  const desc = `Arc diagram with ${nodes.length} node${nodes.length === 1 ? "" : "s"} and ${edges.length} edge${edges.length === 1 ? "" : "s"}`;
  return /* @__PURE__ */ jsxs(
    "svg",
    {
      ...rest,
      "data-hex-arc": true,
      role: "img",
      width,
      height,
      viewBox: `0 0 ${width} ${height}`,
      className: cn("block", className),
      children: [
        /* @__PURE__ */ jsx("title", { children: "Arc diagram" }),
        /* @__PURE__ */ jsx("desc", { children: desc }),
        /* @__PURE__ */ jsx("g", { "data-hex-arc-edges": true, fill: "none", children: laidOut.edges.map((e, i) => {
          const interactive = Boolean(onEdgeHover);
          const fireHover = (edge) => onEdgeHover?.(edge);
          return /* @__PURE__ */ jsx(
            "path",
            {
              "data-hex-arc-edge": true,
              d: e.d,
              className: interactive ? "focus-visible:outline-none focus-visible:outline-2 focus-visible:outline-ring" : void 0,
              stroke: "hsl(var(--primary))",
              strokeOpacity: 0.5,
              strokeWidth: Math.max(1, e.width),
              role: interactive ? "button" : void 0,
              tabIndex: interactive ? 0 : void 0,
              "aria-label": interactive ? `Edge between ${e.edge.source} and ${e.edge.target}${e.edge.value != null ? `, value ${e.edge.value}` : ""}` : void 0,
              style: {
                cursor: interactive ? "pointer" : void 0,
                transition: "stroke-opacity 120ms ease"
              },
              onMouseEnter: interactive ? () => fireHover(e.edge) : void 0,
              onMouseLeave: interactive ? () => fireHover(null) : void 0,
              onFocus: interactive ? () => fireHover(e.edge) : void 0,
              onBlur: interactive ? () => fireHover(null) : void 0
            },
            `${e.edge.source}-${e.edge.target}-${i}`
          );
        }) }),
        /* @__PURE__ */ jsx("g", { "data-hex-arc-nodes": true, children: laidOut.nodes.map((n) => {
          const interactive = Boolean(onNodeClick);
          const handleActivate = () => onNodeClick?.(n.node);
          return /* @__PURE__ */ jsxs(
            "g",
            {
              "data-hex-arc-node": true,
              "data-depth": n.depth,
              className: interactive ? "focus-visible:outline-none focus-visible:outline-2 focus-visible:outline-ring" : void 0,
              role: interactive ? "button" : void 0,
              tabIndex: interactive ? 0 : void 0,
              "aria-label": interactive ? n.node.label : void 0,
              style: interactive ? { cursor: "pointer" } : void 0,
              onClick: interactive ? handleActivate : void 0,
              onKeyDown: interactive ? (e) => activateOnKey(e, handleActivate) : void 0,
              children: [
                /* @__PURE__ */ jsx(
                  "circle",
                  {
                    cx: n.x,
                    cy: n.y,
                    r: nodeRadius,
                    fill: "hsl(var(--primary))",
                    stroke: "hsl(var(--background))",
                    strokeWidth: 2
                  }
                ),
                /* @__PURE__ */ jsx(
                  "text",
                  {
                    x: n.x,
                    y: n.y + nodeRadius + 14,
                    textAnchor: "middle",
                    fontSize: 10,
                    fill: "hsl(var(--foreground))",
                    style: { pointerEvents: "none" },
                    children: n.node.label
                  }
                )
              ]
            },
            n.node.id
          );
        }) })
      ]
    }
  );
}
function layout(nodes, edges, width, height) {
  if (nodes.length === 0) return { nodes: [], edges: [] };
  const margin = 32;
  const baselineY = height - 32;
  const usable = width - margin * 2;
  const step = nodes.length > 1 ? usable / (nodes.length - 1) : 0;
  const positions = /* @__PURE__ */ new Map();
  const laidOutNodes = nodes.map((node, i) => {
    const x = nodes.length === 1 ? width / 2 : margin + step * i;
    positions.set(node.id, { x, y: baselineY, index: i });
    return { node, x, y: baselineY, depth: i };
  });
  const maxValue = edges.reduce((m, e) => Math.max(m, e.value ?? 1), 1);
  const laidOutEdges = edges.map((edge) => {
    const sp = positions.get(edge.source);
    const tp = positions.get(edge.target);
    if (!sp || !tp) return null;
    const [a, b] = sp.x < tp.x ? [sp, tp] : [tp, sp];
    const span = (b.x - a.x) / 2;
    const ctrlY = baselineY - span;
    const d = `M${a.x},${baselineY} C${a.x},${ctrlY} ${b.x},${ctrlY} ${b.x},${baselineY}`;
    return {
      edge,
      d,
      width: 1 + (edge.value ?? 1) / maxValue * 3
    };
  }).filter((e) => e !== null);
  return { nodes: laidOutNodes, edges: laidOutEdges };
}
function activateOnKey(e, fn) {
  if (e.key === "Enter" || e.key === " ") {
    e.preventDefault();
    fn();
  }
}

export { Arc };
//# sourceMappingURL=arc.js.map
//# sourceMappingURL=arc.js.map