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

// src/lib/chart-palette.ts
var CHART_PALETTE = [
  "hsl(var(--chart-1, var(--primary)))",
  "hsl(var(--chart-2, var(--primary)))",
  "hsl(var(--chart-3, var(--primary)))",
  "hsl(var(--chart-4, var(--primary)))",
  "hsl(var(--chart-5, var(--primary)))",
  "hsl(var(--chart-6, var(--primary)))"
];
function pickChartHue(index) {
  const safe = (index % CHART_PALETTE.length + CHART_PALETTE.length) % CHART_PALETTE.length;
  return CHART_PALETTE[safe];
}
function cn(...inputs) {
  return twMerge(clsx(inputs));
}
function depthOpacity(depth, maxDepth) {
  if (maxDepth <= 1) return 0.85;
  const t = (depth - 1) / Math.max(1, maxDepth - 1);
  return 0.85 - t * 0.4;
}
function Sunburst({
  root,
  drillable = true,
  centerLabel,
  size = 400,
  onSegmentClick,
  className,
  ...rest
}) {
  const [d3h, setD3h] = React.useState(null);
  const [d3s, setD3s] = React.useState(null);
  const [focusId, setFocusId] = React.useState(root.id);
  React.useEffect(() => {
    let cancelled = false;
    void Promise.all([import('d3-hierarchy'), import('d3-shape')]).then(([h, s]) => {
      if (cancelled) return;
      setD3h(h);
      setD3s(s);
    });
    return () => {
      cancelled = true;
    };
  }, []);
  React.useEffect(() => {
    setFocusId(root.id);
  }, [root]);
  if (!d3h || !d3s) {
    return /* @__PURE__ */ jsx(
      "div",
      {
        "data-hex-sunburst-loading": true,
        "aria-busy": "true",
        className: cn("inline-block bg-muted/20", className),
        style: { width: size, height: size }
      }
    );
  }
  const focused = findNode(root, focusId) ?? root;
  const radius = size / 2;
  const segments = layout(d3h, focused, radius);
  const maxDepth = segments.reduce((m, s) => Math.max(m, s.depth), 1);
  const arc = d3s.arc().startAngle((s) => s.x0).endAngle((s) => s.x1).innerRadius((s) => s.y0).outerRadius((s) => s.y1).padAngle(5e-3).padRadius(radius);
  const handleSegmentClick = (segment) => {
    onSegmentClick?.(segment.node);
    if (!drillable) return;
    const hasChildren = segment.node.children && segment.node.children.length > 0;
    if (!hasChildren) return;
    setFocusId(segment.node.id);
  };
  const handleCenterClick = () => {
    if (!drillable || focusId === root.id) return;
    setFocusId(root.id);
  };
  const desc = `Sunburst with ${segments.length} segments, focused on "${focused.label}"`;
  return /* @__PURE__ */ jsxs(
    "svg",
    {
      ...rest,
      "data-hex-sunburst": true,
      "data-focus-id": focusId,
      role: "img",
      width: size,
      height: size,
      viewBox: `${-radius} ${-radius} ${size} ${size}`,
      className: cn("block", className),
      children: [
        /* @__PURE__ */ jsx("title", { children: "Sunburst" }),
        /* @__PURE__ */ jsx("desc", { children: desc }),
        /* @__PURE__ */ jsx("g", { "data-hex-sunburst-segments": true, children: segments.filter((s) => s.depth > 0).map((s) => /* @__PURE__ */ jsx(
          "path",
          {
            "data-hex-sunburst-segment": true,
            "data-depth": s.depth,
            d: arc(s) ?? "",
            fill: pickChartHue(s.rootSiblingIdx),
            fillOpacity: depthOpacity(s.depth, maxDepth),
            stroke: "hsl(var(--background))",
            strokeWidth: 1,
            style: drillable || onSegmentClick ? { cursor: "pointer" } : void 0,
            onClick: drillable || onSegmentClick ? () => handleSegmentClick(s) : void 0
          },
          s.node.id
        )) }),
        /* @__PURE__ */ jsx("g", { "data-hex-sunburst-labels": true, "aria-hidden": "true", pointerEvents: "none", children: segments.filter((s) => s.depth > 0 && s.x1 - s.x0 > 0.18).map((s) => {
          const angle = (s.x0 + s.x1) / 2;
          const rMid = (s.y0 + s.y1) / 2;
          const cx = Math.sin(angle) * rMid;
          const cy = -Math.cos(angle) * rMid;
          return /* @__PURE__ */ jsx(
            "text",
            {
              x: cx,
              y: cy,
              textAnchor: "middle",
              dy: "0.35em",
              fontSize: 11,
              fontWeight: 500,
              fill: "hsl(var(--background))",
              style: { paintOrder: "stroke", stroke: "hsl(var(--foreground) / 0.25)", strokeWidth: 2 },
              children: s.node.label
            },
            `${s.node.id}-label`
          );
        }) }),
        /* @__PURE__ */ jsxs(
          "g",
          {
            "data-hex-sunburst-center": true,
            style: drillable && focusId !== root.id ? { cursor: "pointer" } : void 0,
            onClick: drillable ? handleCenterClick : void 0,
            children: [
              /* @__PURE__ */ jsx("circle", { r: radius / 4, fill: "hsl(var(--card))", stroke: "hsl(var(--border))", strokeWidth: 1 }),
              centerLabel ? /* @__PURE__ */ jsx("foreignObject", { x: -radius / 4, y: -radius / 4, width: radius / 2, height: radius / 2, children: /* @__PURE__ */ jsx(
                "div",
                {
                  style: {
                    width: "100%",
                    height: "100%",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    textAlign: "center",
                    fontSize: 12,
                    padding: 4
                  },
                  children: centerLabel
                }
              ) }) : /* @__PURE__ */ jsx(
                "text",
                {
                  textAnchor: "middle",
                  dy: "0.35em",
                  fontSize: 12,
                  fontWeight: 600,
                  fill: "hsl(var(--foreground))",
                  children: focused.label
                }
              )
            ]
          }
        )
      ]
    }
  );
}
function layout(d3h, focused, radius) {
  const hierarchy = d3h.hierarchy(focused).sum((d) => d.children && d.children.length > 0 ? 0 : d.value ?? 0).sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
  const layoutRoot = d3h.partition().size([2 * Math.PI, radius])(hierarchy);
  const segments = [];
  layoutRoot.each((d) => {
    let cursor = d;
    while (cursor && cursor.depth > 1) cursor = cursor.parent;
    const ancestorIdx = cursor?.parent?.children?.indexOf(cursor) ?? 0;
    segments.push({
      node: d.data,
      depth: d.depth,
      x0: d.x0,
      x1: d.x1,
      y0: d.y0,
      y1: d.y1,
      rootSiblingIdx: Math.max(0, ancestorIdx)
    });
  });
  return segments;
}
function findNode(root, id) {
  if (root.id === id) return root;
  if (!root.children) return null;
  for (const c of root.children) {
    const f = findNode(c, id);
    if (f) return f;
  }
  return null;
}

export { Sunburst };
//# sourceMappingURL=sunburst.js.map
//# sourceMappingURL=sunburst.js.map