import React, { useCallback, useState } from 'react';

export type PieChartData = {
  labels?: string[];
  datasets?: Array<{ name?: string; values?: number[]; colors?: string[] }>;
  total?: number;
};

type ChartTooltipState = {
  x: number;
  y: number;
  text: string;
};

const FALLBACK_COLORS = [
  '#6366F1',
  '#8B5CF6',
  '#06B6D4',
  '#EC4899',
  '#F59E0B',
  '#10B981',
  '#EF4444',
  '#3B82F6',
];

const toNumber = (value: unknown): number => {
  const n = Number(value);
  return Number.isFinite(n) && n >= 0 ? n : 0;
};

const formatTooltip = (label: string, value: number, total?: number): string => {
  if (total != null && total > 0) {
    return `${label}: ${value} (${((value / total) * 100).toFixed(1)}%)`;
  }
  return `${label}: ${value}`;
};

const useChartTooltip = () => {
  const [tooltip, setTooltip] = useState<ChartTooltipState | null>(null);

  const show = useCallback(
    (clientX: number, clientY: number, label: string, value: number, total?: number) => {
      setTooltip({ x: clientX, y: clientY, text: formatTooltip(label, value, total) });
    },
    []
  );

  const hide = useCallback(() => setTooltip(null), []);

  return { tooltip, show, hide };
};

const ChartTooltipOverlay: React.FC<{ tooltip: ChartTooltipState | null }> = ({ tooltip }) => {
  if (!tooltip) return null;

  return (
    <div
      className="fixed z-[9999] pointer-events-none px-2.5 py-1.5 rounded text-xs font-medium text-white bg-gray-900 shadow-lg whitespace-nowrap"
      style={{ left: tooltip.x, top: tooltip.y - 8, transform: 'translate(-50%, -100%)' }}
      role="tooltip"
    >
      {tooltip.text}
    </div>
  );
};

type PieChartProps = {
  data: PieChartData | null;
  emptyMessage?: string;
};

const PieChart: React.FC<PieChartProps> = ({ data, emptyMessage = 'No data available' }) => {
  const { tooltip, show, hide } = useChartTooltip();
  const labels = data?.labels || [];
  const values = (data?.datasets?.[0]?.values || []).map(toNumber);
  const datasetColors = data?.datasets?.[0]?.colors;
  const colors =
    datasetColors && datasetColors.length === values.length
      ? datasetColors
      : values.map((_, i) => FALLBACK_COLORS[i % FALLBACK_COLORS.length]);

  const total = data?.total ?? values.reduce((sum, val) => sum + val, 0);

  if (total <= 0 || labels.length === 0) {
    return (
      <div className="h-48 flex items-center justify-center text-gray-400 text-sm">{emptyMessage}</div>
    );
  }

  const radius = 100;
  const cx = radius + 10;
  const cy = radius + 10;

  let cumulative = 0;
  const slices = values.map((value, i) => {
    const startAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
    cumulative += value;
    const endAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
    const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;

    const x1 = cx + radius * Math.cos(startAngle);
    const y1 = cy + radius * Math.sin(startAngle);
    const x2 = cx + radius * Math.cos(endAngle);
    const y2 = cy + radius * Math.sin(endAngle);

    return {
      path: `M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`,
      color: colors[i],
      label: labels[i],
      value,
      percentage: ((value / total) * 100).toFixed(1),
    };
  });

  const isSingleSlice = slices.length === 1;

  return (
    <div className="flex flex-col md:flex-row items-center justify-around gap-4" onMouseLeave={hide}>
      <ChartTooltipOverlay tooltip={tooltip} />
      <svg width={cx * 2} height={cy * 2} viewBox={`0 0 ${cx * 2} ${cy * 2}`} className="max-w-xs shrink-0">
        {isSingleSlice ? (
          <circle
            cx={cx}
            cy={cy}
            r={radius}
            fill={slices[0].color}
            className="hover:opacity-90 transition-opacity drop-shadow-lg"
            onMouseEnter={(e) => show(e.clientX, e.clientY, slices[0].label, slices[0].value, total)}
            onMouseMove={(e) => show(e.clientX, e.clientY, slices[0].label, slices[0].value, total)}
            onMouseLeave={hide}
          >
            <title>{formatTooltip(slices[0].label, slices[0].value, total)}</title>
          </circle>
        ) : (
          slices.map((slice, i) => (
            <path
              key={i}
              d={slice.path}
              fill={slice.color}
              className="hover:opacity-80 transition-opacity drop-shadow-md"
              onMouseEnter={(e) => show(e.clientX, e.clientY, slice.label, slice.value, total)}
              onMouseMove={(e) => show(e.clientX, e.clientY, slice.label, slice.value, total)}
              onMouseLeave={hide}
            >
              <title>{formatTooltip(slice.label, slice.value, total)}</title>
            </path>
          ))
        )}
      </svg>

      <div className="flex flex-col gap-2 min-w-[140px]">
        {slices.map((slice, i) => (
          <div key={i} className="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-300">
            <span className="w-3 h-3 rounded-full shrink-0" style={{ backgroundColor: slice.color }} />
            <span className="truncate flex-1">{slice.label}</span>
            <span className="font-semibold text-gray-800 dark:text-white">{slice.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

export default PieChart;
