"use client";

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

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";

import { JsonViewPopup } from "../json-view-popup";
import { sanitizeCssVariableName } from "./shared.tool-invocation";

// PieChart component props interface
export interface PieChartProps {
  // Chart title (required)
  title: string;
  // Chart data array (required)
  data: Array<{
    label: string; // Item label
    value: number; // Item value
  }>;
  // Value unit (optional, e.g., "visitors", "users", etc.)
  unit?: string;
  // Chart description (optional)
  description?: string;
  prefix?: string;
  jsonView?: boolean;
}

// Color variable names (chart-1 ~ chart-5)
const chartColors = [
  "var(--chart-1)",
  "var(--chart-2)",
  "var(--chart-3)",
  "var(--chart-4)",
  "var(--chart-5)",
];

// Function to format large numbers with k, M, B, T units
function formatLargeNumber(num: number | null | undefined): string {
  // Handle null, undefined, or invalid numbers
  if (num == null || isNaN(num) || !isFinite(num)) {
    return "0";
  }

  // Handle negative numbers
  if (num < 0) {
    return `-${formatLargeNumber(-num)}`;
  }

  // Handle zero
  if (num === 0) {
    return "0";
  }

  if (num < 1000) {
    return num.toString();
  }

  const units = [
    "",
    "k",
    "M",
    "B",
    "T",
    "Qa",
    "Qi",
    "Sx",
    "Sp",
    "Oc",
    "No",
    "Dc",
  ];
  let unitIndex = 0;
  let value = num;

  while (value >= 1000 && unitIndex < units.length - 1) {
    value /= 1000;
    unitIndex++;
  }

  return `${value.toFixed(1)}${units[unitIndex]}`;
}

export function PieChart(props: PieChartProps) {
  const { title, data, unit, description, prefix, jsonView = true } = props;
  // Calculate total value
  const total = React.useMemo(() => {
    return data.reduce((acc, curr) => acc + curr.value, 0);
  }, [data]);

  // Generate chart configuration dynamically
  const chartConfig = React.useMemo(() => {
    const config: ChartConfig = {};

    // Set value unit
    if (unit) {
      config.value = {
        label: unit,
      };
    }

    // Configure each data item
    data.forEach((item, index) => {
      // Colors cycle through chart-1 ~ chart-5
      const colorIndex = index % chartColors.length;
      config[sanitizeCssVariableName(item.label)] = {
        label: item.label,
        color: chartColors[colorIndex],
      };
    });

    return config;
  }, [data, unit]);

  // Generate actual chart data
  const chartData = React.useMemo(() => {
    return data.map((item) => ({
      name: item.label,
      label: item.label,
      value: item.value,
      // Add fill property if needed
      fill: `var(--color-${sanitizeCssVariableName(item.label)})`,
    }));
  }, [data]);

  return (
    <Card className="flex flex-col bg-card">
      <CardHeader className="items-center pb-0 flex flex-col gap-2 relative">
        <CardTitle className="flex items-center">
          {prefix ?? "Pie Chart - "}
          {title}
          {jsonView && (
            <div className="absolute right-4 top-0">
              <JsonViewPopup data={props} />
            </div>
          )}
        </CardTitle>
        {description && <CardDescription>{description}</CardDescription>}
      </CardHeader>
      <CardContent className="flex-1 pb-0">
        <ChartContainer
          config={chartConfig}
          className="mx-auto aspect-square max-h-[300px]"
        >
          <RechartsPieChart>
            <ChartTooltip
              cursor={false}
              content={<ChartTooltipContent hideLabel />}
            />
            <Pie
              data={chartData}
              dataKey="value"
              nameKey="name"
              innerRadius={60}
              strokeWidth={5}
            >
              <Label
                content={({ viewBox }) => {
                  if (viewBox && "cx" in viewBox && "cy" in viewBox) {
                    return (
                      <text
                        x={viewBox.cx}
                        y={viewBox.cy}
                        textAnchor="middle"
                        dominantBaseline="middle"
                      >
                        <tspan
                          x={viewBox.cx}
                          y={viewBox.cy}
                          className="fill-foreground text-3xl font-bold"
                        >
                          {formatLargeNumber(total)}
                        </tspan>
                        {unit && (
                          <tspan
                            x={viewBox.cx}
                            y={(viewBox.cy || 0) + 24}
                            className="fill-muted-foreground"
                          >
                            {unit}
                          </tspan>
                        )}
                      </text>
                    );
                  }
                }}
              />
            </Pie>
          </RechartsPieChart>
        </ChartContainer>
      </CardContent>
    </Card>
  );
}
