"use client";

// src/components/ui/chart.tsx
import * as React from "react";
import * as RechartsPrimitive from "recharts";

// src/lib/utils.ts
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
function cn(...inputs) {
  return twMerge(clsx(inputs));
}

// src/components/ui/chart.tsx
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var THEMES = { light: "", dark: ".dark" };
var ChartContext = React.createContext(null);
function useChart() {
  const context = React.useContext(ChartContext);
  if (!context) {
    throw new Error("useChart must be used within a <ChartContainer />");
  }
  return context;
}
var CHART_RESIZE_DEBOUNCE_MS = 120;
function ChartContainer({
  id,
  className,
  children,
  config,
  debounce = CHART_RESIZE_DEBOUNCE_MS,
  ...props
}) {
  const uniqueId = React.useId();
  const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
  const chartContextValue = React.useMemo(() => ({ config }), [config]);
  return /* @__PURE__ */ jsx(ChartContext.Provider, { value: chartContextValue, children: /* @__PURE__ */ jsxs(
    "div",
    {
      "data-slot": "chart",
      "data-chart": chartId,
      className: cn(
        "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_line]:stroke-border/50 [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_line]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-surface]:outline-hidden",
        className
      ),
      ...props,
      children: [
        /* @__PURE__ */ jsx(ChartStyle, { id: chartId, config }),
        /* @__PURE__ */ jsx(RechartsPrimitive.ResponsiveContainer, { debounce, children })
      ]
    }
  ) });
}
var CSS_KEY_PATTERN = /^[A-Za-z0-9_-]+$/;
var SAFE_COLOR_PATTERN = new RegExp(
  [
    /^#[0-9a-fA-F]{3,8}$/,
    // #rgb / #rrggbb / #rrggbbaa
    /^rgba?\([^;{}<>"'\\]*\)$/,
    // rgb()/rgba()
    /^hsla?\([^;{}<>"'\\]*\)$/,
    // hsl()/hsla()
    /^hwb\([^;{}<>"'\\]*\)$/,
    // hwb()
    /^lab\([^;{}<>"'\\]*\)$/,
    // lab()
    /^lch\([^;{}<>"'\\]*\)$/,
    // lch()
    /^oklab\([^;{}<>"'\\]*\)$/,
    // oklab()
    /^oklch\([^;{}<>"'\\]*\)$/,
    // oklch()
    /^color\([^;{}<>"'\\]*\)$/,
    // color()
    /^color-mix\([^;{}<>"'\\]*\)$/,
    // color-mix()
    /^var\(--[A-Za-z0-9_-]+(?:\s*,[^;{}<>"'\\]+)?\)$/,
    // var(--token[, fallback])
    /^[a-zA-Z]+$/
    // named colors + currentColor/transparent
  ].map((re) => re.source).join("|")
);
function sanitizeChartColor(color) {
  const trimmed = color.trim();
  if (!trimmed) return null;
  if (/[;{}<>"'\\]/.test(trimmed)) return null;
  return SAFE_COLOR_PATTERN.test(trimmed) ? trimmed : null;
}
var ChartStyle = ({ id, config }) => {
  const colorConfig = Object.entries(config).filter(
    ([, config2]) => config2.theme || config2.color
  );
  if (!colorConfig.length) {
    return null;
  }
  if (!CSS_KEY_PATTERN.test(id)) {
    return null;
  }
  return /* @__PURE__ */ jsx(
    "style",
    {
      dangerouslySetInnerHTML: {
        __html: Object.entries(THEMES).flatMap(([theme, prefix]) => {
          const lines = colorConfig.flatMap(([key, itemConfig]) => {
            if (!CSS_KEY_PATTERN.test(key)) return [];
            const rawColor = itemConfig.theme?.[theme] || itemConfig.color;
            if (!rawColor) return [];
            const safeColor = sanitizeChartColor(rawColor);
            return safeColor ? [`  --color-${key}: ${safeColor};`] : [];
          });
          if (!lines.length) return [];
          return [`
${prefix} [data-chart=${id}] {
${lines.join("\n")}
}
`];
        }).join("\n")
      }
    }
  );
};
var ChartTooltip = RechartsPrimitive.Tooltip;
function chartTooltipKeyboardSyncProps(keyboardActiveIndex) {
  const hasKbd = typeof keyboardActiveIndex === "number" && keyboardActiveIndex >= 0;
  return {
    key: hasKbd ? `kbd-${keyboardActiveIndex}` : "kbd-off",
    props: hasKbd ? { defaultIndex: keyboardActiveIndex } : {}
  };
}
function ChartTooltipLabel({
  hideLabel,
  payload,
  label,
  labelFormatter,
  labelClassName,
  labelKey,
  config
}) {
  if (hideLabel || !payload?.length) {
    return null;
  }
  const [item] = payload;
  const key = `${labelKey || item?.dataKey || item?.name || "value"}`;
  const itemConfig = getPayloadConfigFromPayload(config, item, key);
  const value = !labelKey && typeof label === "string" ? config[label]?.label || label : itemConfig?.label;
  if (labelFormatter) {
    return /* @__PURE__ */ jsx("div", { className: cn("font-medium", labelClassName), children: labelFormatter(value, payload) });
  }
  if (!value) {
    return null;
  }
  return /* @__PURE__ */ jsx("div", { className: cn("font-medium", labelClassName), children: value });
}
function ChartTooltipContent({
  active,
  payload,
  className,
  indicator = "dot",
  hideLabel = false,
  hideIndicator = false,
  label,
  labelFormatter,
  labelClassName,
  formatter,
  color,
  nameKey,
  labelKey
}) {
  const { config } = useChart();
  const visiblePayload = React.useMemo(
    () => payload?.filter((item) => item.type !== "none") ?? [],
    [payload]
  );
  if (!active || !visiblePayload.length) {
    return null;
  }
  const nestLabel = visiblePayload.length === 1 && indicator !== "dot";
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: cn(
        "grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
        className
      ),
      children: [
        !nestLabel ? /* @__PURE__ */ jsx(
          ChartTooltipLabel,
          {
            hideLabel,
            payload,
            label,
            labelFormatter,
            labelClassName,
            labelKey,
            config
          }
        ) : null,
        /* @__PURE__ */ jsx("div", { className: "grid gap-1.5", children: visiblePayload.map((item, index) => {
          const key = `${nameKey || item.name || item.dataKey || "value"}`;
          const itemConfig = getPayloadConfigFromPayload(config, item, key);
          const indicatorColor = color || item.payload.fill || item.color;
          return /* @__PURE__ */ jsx(
            "div",
            {
              className: cn(
                "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
                indicator === "dot" && "items-center"
              ),
              children: formatter && item?.value !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxs(Fragment, { children: [
                itemConfig?.icon ? /* @__PURE__ */ jsx(itemConfig.icon, {}) : !hideIndicator && /* @__PURE__ */ jsx(
                  "div",
                  {
                    className: cn(
                      "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
                      {
                        "size-2.5": indicator === "dot",
                        "w-1": indicator === "line",
                        "w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
                        "my-0.5": nestLabel && indicator === "dashed"
                      }
                    ),
                    style: {
                      "--color-bg": indicatorColor,
                      "--color-border": indicatorColor
                    }
                  }
                ),
                /* @__PURE__ */ jsxs(
                  "div",
                  {
                    className: cn(
                      "flex flex-1 justify-between leading-none",
                      nestLabel ? "items-end" : "items-center"
                    ),
                    children: [
                      /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", children: [
                        nestLabel ? /* @__PURE__ */ jsx(
                          ChartTooltipLabel,
                          {
                            hideLabel,
                            payload,
                            label,
                            labelFormatter,
                            labelClassName,
                            labelKey,
                            config
                          }
                        ) : null,
                        /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: itemConfig?.label || item.name })
                      ] }),
                      item.value && /* @__PURE__ */ jsx("span", { className: "font-mono font-medium text-foreground tabular-nums", children: item.value.toLocaleString() })
                    ]
                  }
                )
              ] })
            },
            `${item.dataKey ?? item.name ?? index}`
          );
        }) })
      ]
    }
  );
}
var ChartLegend = RechartsPrimitive.Legend;
function ChartLegendContent({
  className,
  hideIcon = false,
  payload,
  verticalAlign = "bottom",
  nameKey
}) {
  const { config } = useChart();
  const visiblePayload = React.useMemo(
    () => payload?.filter((item) => item.type !== "none") ?? [],
    [payload]
  );
  if (!visiblePayload.length) {
    return null;
  }
  return /* @__PURE__ */ jsx(
    "div",
    {
      className: cn(
        "flex items-center justify-center gap-4",
        verticalAlign === "top" ? "pb-3" : "pt-3",
        className
      ),
      children: visiblePayload.map((item) => {
        const key = `${nameKey || item.dataKey || "value"}`;
        const itemConfig = getPayloadConfigFromPayload(config, item, key);
        return /* @__PURE__ */ jsxs(
          "div",
          {
            className: cn(
              "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
            ),
            children: [
              itemConfig?.icon && !hideIcon ? /* @__PURE__ */ jsx(itemConfig.icon, {}) : /* @__PURE__ */ jsx(
                "div",
                {
                  className: "size-2 shrink-0 rounded-[2px]",
                  style: {
                    backgroundColor: item.color
                  }
                }
              ),
              itemConfig?.label
            ]
          },
          item.value
        );
      })
    }
  );
}
function getPayloadConfigFromPayload(config, payload, key) {
  if (typeof payload !== "object" || payload === null) {
    return void 0;
  }
  const payloadPayload = "payload" in payload && typeof payload.payload === "object" && payload.payload !== null ? payload.payload : void 0;
  let configLabelKey = key;
  if (key in payload && typeof payload[key] === "string") {
    configLabelKey = payload[key];
  } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === "string") {
    configLabelKey = payloadPayload[key];
  }
  return configLabelKey in config ? config[configLabelKey] : config[key];
}
export {
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartStyle,
  ChartTooltip,
  ChartTooltipContent,
  chartTooltipKeyboardSyncProps
};
//# sourceMappingURL=chart.js.map