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,
  DoughnutLegendRow,
  FALLBACK_PRIMARY,
  FALLBACK_SECONDARY,
} from "./chart-shared";

ChartJS.register(ArcElement, DoughnutController, Tooltip);

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

export interface PropertyCashflowDoughnutChartProps {
  /** Total rental income or inflows in dollars */
  income?: number | null;
  /** Total expenses or outflows in dollars */
  expenses?: number | 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 PropertyCashflowDoughnutChart({
  income,
  expenses,
  title = "Property Cashflow",
  showLegend = true,
  height = 200,
  width = "100%",
  className,
  isLoading = false,
}: PropertyCashflowDoughnutChartProps) {
  const themeVars = useThemeVars();
  const brandPrimary: string =
    (themeVars["--theme-primary"] as string | undefined) || FALLBACK_PRIMARY;
  const brandSecondary: string =
    (themeVars["--theme-secondary"] as string | undefined) ||
    FALLBACK_SECONDARY;
  const fontFamily: string =
    (themeVars["--font-sans"] as string | undefined) || "Figtree, sans-serif";

  const incomeVal = Math.max(0, income ?? 0);
  const expensesVal = Math.max(0, expenses ?? 0);
  const total = incomeVal + expensesVal;
  const netCashflow = incomeVal - expensesVal;
  const hasData = total > 0;

  const chartData = useMemo<ChartData<"doughnut">>(
    () => ({
      labels: ["Income", "Expenses"],
      datasets: [
        {
          data: [incomeVal, expensesVal],
          backgroundColor: [brandPrimary, brandSecondary],
          borderWidth: 0,
          hoverOffset: 4,
        },
      ],
    }),
    [incomeVal, expensesVal, brandPrimary, brandSecondary],
  );

  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],
  );

  const incomePct =
    total > 0 ? `${((incomeVal / total) * 100).toFixed(1)}%` : "0%";
  const expensesPct =
    total > 0 ? `${((expensesVal / total) * 100).toFixed(1)}%` : "0%";

  const netLabel = netCashflow >= 0 ? "Surplus" : "Deficit";

  return (
    <Card
      className={cn("w-full py-4 sm:py-6 gap-2", className)}
      style={{ maxWidth: width, fontFamily }}
    >
      <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}__${brandSecondary}`}
                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(Math.abs(netCashflow))}
                </div>
                <div className="text-[11px] text-muted-foreground leading-none mt-1">
                  {netLabel}
                </div>
              </div>
            </div>
            {showLegend && (
              <div className="flex flex-col gap-2">
                <DoughnutLegendRow
                  label="Income"
                  color={brandPrimary}
                  value={incomeVal}
                  percent={incomePct}
                />
                <DoughnutLegendRow
                  label="Expenses"
                  color={brandSecondary}
                  value={expensesVal}
                  percent={expensesPct}
                />
              </div>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
