"use client";

import * as React from "react";
import { Cell, Pie, PieChart } from "recharts";

import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
import { pieGeometryForSliceCount } from "@/lib/chart/positive-pie-slices";
import { cn } from "@/lib/utils";

import type { DashboardChartSlice } from "./types";

const chartConfig = {
  value: { label: "Value" },
} satisfies ChartConfig;

type ResponsiveDonutChartProps = {
  slices: DashboardChartSlice[];
  className?: string;
  minSize?: number;
  maxSize?: number;
};

export function ResponsiveDonutChart({
  slices,
  className,
  minSize = 140,
  maxSize = 240,
}: ResponsiveDonutChartProps) {
  const hostRef = React.useRef<HTMLDivElement>(null);
  const [size, setSize] = React.useState(minSize);

  React.useEffect(() => {
    const el = hostRef.current;
    if (!el) return;

    let frame = 0;
    const update = () => {
      cancelAnimationFrame(frame);
      frame = requestAnimationFrame(() => {
        const box = el.getBoundingClientRect();
        const next = Math.max(minSize, Math.floor(Math.min(box.width, box.height || box.width, maxSize)));
        setSize((prev) => (prev === next ? prev : next));
      });
    };

    update();
    const ro = new ResizeObserver(update);
    ro.observe(el);
    return () => {
      cancelAnimationFrame(frame);
      ro.disconnect();
    };
  }, [maxSize, minSize]);

  if (slices.length === 0) {
    return (
      <div
        className={cn(
          "flex aspect-square w-full items-center justify-center rounded-full border border-dashed border-border/60 bg-muted/10 text-xs text-muted-foreground",
          className,
        )}
        style={{ minHeight: minSize }}
      >
        No chart data
      </div>
    );
  }

  const { paddingAngle, cornerRadius: baseCorner } = pieGeometryForSliceCount(slices.length);
  const outerRadius = Math.max(48, Math.floor(size * 0.44));
  const innerRadius = Math.max(32, Math.floor(outerRadius * 0.72));
  const thickness = outerRadius - innerRadius;
  const cornerRadius = Math.min(baseCorner, Math.max(4, Math.floor(thickness * 0.45)));

  return (
    <div
      ref={hostRef}
      className={cn("relative flex aspect-square w-full items-center justify-center overflow-visible", className)}
      style={{ minHeight: minSize }}
    >
      <ChartContainer
        config={chartConfig}
        className="aspect-square shrink-0 overflow-visible [&_.recharts-pie-sector]:outline-none [&_.recharts-tooltip-wrapper]:z-20"
        style={{ height: size, width: size }}
      >
        <PieChart margin={{ top: 8, right: 8, bottom: 8, left: 8 }}>
          <ChartTooltip
            cursor={false}
            isAnimationActive={false}
            allowEscapeViewBox={{ x: true, y: true }}
            offset={12}
            wrapperStyle={{ zIndex: 20, outline: "none" }}
            content={
              <ChartTooltipContent
                hideLabel
                hideIndicator
                className="z-20 border bg-background/95 shadow-lg backdrop-blur-sm"
                formatter={(_value, _name, item) => {
                  const payload = item.payload as DashboardChartSlice;
                  return (
                    <div className="space-y-0.5">
                      <p className="font-semibold">{payload.name}</p>
                      {payload.label ? <p className="tabular-nums">{payload.label}</p> : null}
                      {payload.pct != null ? (
                        <p className="text-muted-foreground text-xs">{payload.pct.toFixed(1)}%</p>
                      ) : null}
                    </div>
                  );
                }}
              />
            }
          />
          <Pie
            data={slices}
            dataKey="value"
            nameKey="name"
            innerRadius={innerRadius}
            outerRadius={outerRadius}
            paddingAngle={paddingAngle}
            cornerRadius={cornerRadius}
            stroke="hsl(var(--card))"
            strokeWidth={2}
            isAnimationActive={false}
          >
            {slices.map((slice) => (
              <Cell key={slice.id} fill={slice.fill} className="outline-none" />
            ))}
          </Pie>
        </PieChart>
      </ChartContainer>
    </div>
  );
}
