import React, { useMemo } from "react";
import {
  Chart as ChartJS,
  ArcElement,
  DoughnutController,
  Tooltip,
  type ChartOptions,
  type ChartData,
} from "chart.js";
import { Chart } from "react-chartjs-2";
import { useThemeVars } from "@/lib/theme-provider";
import { Card, CardContent, CardHeader, CardTitle } from "./card";
import { Empty, EmptyDescription } from "./empty";
import { Skeleton } from "./skeleton";
import { cn } from "@/lib/utils";
import {
  formatAbbrev,
  hexToRgba,
  DATASET_ALPHAS,
  FALLBACK_PRIMARY,
  DoughnutLegendRow,
} from "./chart-shared";

ChartJS.register(ArcElement, DoughnutController, Tooltip);

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface LiabilitySegment {
  label: string;
  /** Value in dollars */
  value: number;
}

export interface TransactionsLiabilitiesBreakdownChartProps {
  segments?: LiabilitySegment[] | null;
  title?: string;
  showLegend?: boolean;
  /** Chart canvas height in pixels */
  height?: number;
  /** Card max-width in pixels or CSS string */
  width?: number | string;
  className?: string;
  /** Show skeleton loading state instead of the chart */
  isLoading?: boolean;
}

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function TransactionsLiabilitiesBreakdownChart({
  segments,
  title = "Liabilities Breakdown",
  showLegend = true,
  height = 200,
  width = "100%",
  className,
  isLoading = false,
}: TransactionsLiabilitiesBreakdownChartProps) {
  const themeVars = useThemeVars();
  const brandPrimary: string =
    (themeVars["--theme-primary"] as string | undefined) || FALLBACK_PRIMARY;
  const fontFamily: string =
    (themeVars["--font-sans"] as string | undefined) || "Figtree, sans-serif";

  const hasData = !!segments?.length && segments.some((s) => s.value > 0);

  const total = useMemo(
    () => segments?.reduce((sum, s) => sum + s.value, 0) ?? 0,
    [segments],
  );

  const colors = useMemo(
    () =>
      (segments ?? []).map((_, i) =>
        hexToRgba(brandPrimary, DATASET_ALPHAS[i % DATASET_ALPHAS.length]),
      ),
    [segments, brandPrimary],
  );

  const chartData = useMemo<ChartData<"doughnut">>(
    () => ({
      labels: segments?.map((s) => s.label) ?? [],
      datasets: [
        {
          data: segments?.map((s) => s.value) ?? [],
          backgroundColor: colors,
          borderWidth: 0,
          hoverOffset: 4,
        },
      ],
    }),
    [segments, colors],
  );

  const options = useMemo<ChartOptions<"doughnut">>(
    () => ({
      responsive: true,
      maintainAspectRatio: false,
      cutout: "68%",
      animation: { duration: 600, easing: "easeOutQuart" },
      plugins: {
        legend: { display: false },
        tooltip: {
          padding: 10,
          cornerRadius: 0,
          titleFont: { size: 11, weight: 600 },
          bodyFont: { size: 12, weight: 500 },
          callbacks: {
            label: (ctx) => {
              const val = ctx.raw as number;
              const pct =
                total > 0 ? `${((val / total) * 100).toFixed(1)}%` : "0%";
              return ` ${ctx.label}: ${formatAbbrev(val)} (${pct})`;
            },
          },
        },
      },
    }),
    [total],
  );

  return (
    <Card
      className={cn("w-full py-4 sm:py-6 gap-2", className)}
      style={{ maxWidth: width, fontFamily }}
    >
      {title && (
        <CardHeader className="px-3 sm:px-6">
          <CardTitle className="text-xs font-semibold uppercase tracking-wide">
            {title}
          </CardTitle>
        </CardHeader>
      )}

      <CardContent className="px-3 sm:px-6">
        {isLoading ? (
          <Skeleton style={{ height, width: "100%" }} />
        ) : !hasData ? (
          <Empty className="flex-none p-4" style={{ height }}>
            <EmptyDescription>No data available</EmptyDescription>
          </Empty>
        ) : (
          <div className="flex flex-col gap-4">
            <div style={{ height, width: "100%", position: "relative" }}>
              <Chart
                key={brandPrimary}
                type="doughnut"
                data={chartData}
                options={options}
                aria-label={title}
              />
              <div
                style={{
                  position: "absolute",
                  top: "50%",
                  left: "50%",
                  transform: "translate(-50%, -50%)",
                  textAlign: "center",
                  pointerEvents: "none",
                }}
              >
                <div className="text-base font-semibold leading-tight">
                  {formatAbbrev(total)}
                </div>
                <div className="text-[11px] text-muted-foreground leading-none mt-1">
                  Total
                </div>
              </div>
            </div>
            {showLegend && (
              <div className="flex flex-col gap-2">
                {segments!.map((s, i) => (
                  <DoughnutLegendRow
                    key={s.label}
                    label={s.label}
                    color={colors[i]}
                    value={s.value}
                    percent={
                      total > 0
                        ? `${((s.value / total) * 100).toFixed(1)}%`
                        : "0%"
                    }
                  />
                ))}
              </div>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
