"use client";

import * as React from "react";
import { BarChart3, PieChart as PieChartIcon } from "lucide-react";
import { Bar, BarChart, CartesianGrid, Cell, Pie, PieChart, XAxis, YAxis } from "recharts";

import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from "@/components/ui/chart";
import { pieGeometryForSliceCount } from "@/lib/chart/positive-pie-slices";
import type { DriftAllocationComparison } from "@/app/customer/[tenant]/settings/_lib/tenant-settings-server-api";

import { DRIFT_RULE_COLORS } from "./drift-rule-colors";
import { DriftSection } from "./drift-ui-primitives";
import { formatDriftPct } from "./format-drift";

type SimulatedRuleRow = {
  rule_label: string;
  ideal_pct: number;
  actual_pct: number;
  sim_actual_pct: number;
  is_virtual: boolean;
};

type AllocationChartsProps = {
  comparison: DriftAllocationComparison[];
  simRows?: SimulatedRuleRow[] | null;
  mode: "real" | "simulated";
  layout?: "full" | "compact";
};

type DonutRow = {
  name: string;
  value: number;
  isVirtual?: boolean;
  color?: string;
};

type DonutLegendRow = DonutRow & {
  fill: string;
};

function donutTooltipContent(name: string, value: number) {
  return (
    <div className="flex min-w-0 flex-col gap-0.5">
      <span className="max-w-[220px] break-words text-foreground">{name}</span>
      <span className="font-medium tabular-nums text-foreground/80">{formatDriftPct(value)}</span>
    </div>
  );
}

function DriftAllocationDonut({
  data,
  config,
  resolveColor,
}: {
  data: DonutRow[];
  config: ChartConfig;
  resolveColor: (row: DonutRow, index: number) => string;
}) {
  const chartData = React.useMemo<DonutLegendRow[]>(
    () =>
      data.map((row, index) => ({
        ...row,
        fill: resolveColor(row, index),
      })),
    [data, resolveColor],
  );
  const { paddingAngle, cornerRadius } = pieGeometryForSliceCount(chartData.length);

  if (!chartData.length) {
    return null;
  }

  return (
    <div className="flex flex-col items-center">
      <ChartContainer config={config} className="mx-auto aspect-square h-[260px] w-full max-w-[300px]">
        <PieChart>
          <ChartTooltip
            content={
              <ChartTooltipContent
                hideLabel
                formatter={(value, _name, item) =>
                  donutTooltipContent(String(item?.payload?.name ?? _name ?? ""), Number(value))
                }
                nameKey="name"
              />
            }
          />
          <Pie
            data={chartData}
            dataKey="value"
            nameKey="name"
            innerRadius={62}
            outerRadius={92}
            paddingAngle={paddingAngle}
            cornerRadius={cornerRadius}
            stroke="hsl(var(--card))"
            strokeWidth={2}
            isAnimationActive={false}
          >
            {chartData.map((row) => (
              <Cell key={row.name} fill={row.fill} className="stroke-background" />
            ))}
          </Pie>
        </PieChart>
      </ChartContainer>
    </div>
  );
}

export function AllocationCharts({ comparison, simRows, mode, layout }: AllocationChartsProps) {
  const resolvedLayout = layout ?? (mode === "simulated" ? "compact" : "full");

  const columnData = React.useMemo(() => {
    if (mode === "simulated" && simRows) {
      return simRows
        .filter((row) => !row.is_virtual)
        .map((row, index) => ({
          name: row.rule_label,
          ideal: row.ideal_pct,
          actual: row.actual_pct,
          simulated: row.sim_actual_pct,
          fill: DRIFT_RULE_COLORS[index % DRIFT_RULE_COLORS.length],
        }));
    }
    return comparison.map((row, index) => ({
      name: row.rule_label,
      ideal: row.ideal_pct,
      actual: row.actual_pct,
      fill: DRIFT_RULE_COLORS[index % DRIFT_RULE_COLORS.length],
    }));
  }, [comparison, mode, simRows]);

  const actualDonutSource =
    mode === "simulated" && simRows
      ? simRows.map((row) => ({
          name: row.rule_label,
          value: Math.max(row.sim_actual_pct, 0),
          isVirtual: row.is_virtual,
        }))
      : comparison.map((row) => ({
          name: row.rule_label,
          value: Math.max(row.actual_pct, 0),
          isVirtual: false,
        }));

  const idealDonutSource = comparison.map((row, index) => ({
    name: row.rule_label,
    value: Math.max(row.ideal_pct, 0),
    isVirtual: false,
    color: DRIFT_RULE_COLORS[index % DRIFT_RULE_COLORS.length],
  }));

  const barConfig = {
    ideal: { label: "Ideal %", color: "hsl(var(--chart-1))" },
    actual: { label: "Actual %", color: "hsl(var(--chart-2))" },
    ...(mode === "simulated"
      ? { simulated: { label: "Simulated %", color: "hsl(var(--chart-3))" } }
      : {}),
  } satisfies ChartConfig;

  const donutConfig = Object.fromEntries(
    actualDonutSource.map((row, index) => [
      row.name,
      {
        label: row.name,
        color: row.isVirtual ? "#f59e0b" : DRIFT_RULE_COLORS[index % DRIFT_RULE_COLORS.length],
      },
    ]),
  ) satisfies ChartConfig;

  const idealDonutConfig = Object.fromEntries(
    idealDonutSource.map((row) => [row.name, { label: row.name, color: row.color }]),
  ) satisfies ChartConfig;

  if (!columnData.length) {
    return <p className="py-8 text-center text-muted-foreground text-sm">No allocation rules to chart.</p>;
  }

  const barChart = (
    <ChartContainer config={barConfig} className="aspect-auto h-[300px] w-full sm:h-[320px]">
      <BarChart data={columnData} margin={{ left: 4, right: 8, top: 8, bottom: 48 }}>
        <CartesianGrid vertical={false} strokeDasharray="3 3" className="stroke-border/50" />
        <XAxis
          dataKey="name"
          tickLine={false}
          axisLine={false}
          tick={false}
          height={12}
        />
        <YAxis tickFormatter={(v) => `${v}%`} width={44} tick={{ fontSize: 11 }} axisLine={false} tickLine={false} />
        <ChartTooltip content={<ChartTooltipContent formatter={(value) => formatDriftPct(Number(value))} />} />
        <Bar dataKey="ideal" fill="var(--color-ideal)" radius={[4, 4, 0, 0]} maxBarSize={36} />
        <Bar dataKey="actual" fill="var(--color-actual)" radius={[4, 4, 0, 0]} maxBarSize={36} />
        {mode === "simulated" ? (
          <Bar dataKey="simulated" fill="var(--color-simulated)" radius={[4, 4, 0, 0]} maxBarSize={36} />
        ) : null}
      </BarChart>
    </ChartContainer>
  );

  const actualPie = (
    <DriftAllocationDonut
      data={actualDonutSource}
      config={donutConfig}
      resolveColor={(row, index) =>
        row.isVirtual ? "#f59e0b" : DRIFT_RULE_COLORS[index % DRIFT_RULE_COLORS.length]
      }
    />
  );

  if (resolvedLayout === "compact") {
    return (
      <div className="grid gap-4 lg:grid-cols-2">
        <DriftSection
          title={`Ideal vs ${mode === "simulated" ? "Actual vs Simulated" : "Actual"}`}
          icon={BarChart3}
        >
          <div className="p-4 sm:p-5">{barChart}</div>
        </DriftSection>
        <DriftSection title={mode === "simulated" ? "Simulated mix" : "Actual mix"} icon={PieChartIcon}>
          <div className="p-4 sm:p-5">{actualPie}</div>
        </DriftSection>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <DriftSection
        title="Actual vs ideal comparison"
        description="Side-by-side view of target and current allocation by segment."
        icon={BarChart3}
      >
        <div className="p-4 sm:p-5">{barChart}</div>
      </DriftSection>

      <div className="grid gap-4 lg:grid-cols-2">
        <DriftSection
          title="Actual allocation"
          description="Current portfolio split by segment."
          icon={PieChartIcon}
        >
          <div className="p-4 sm:p-5">{actualPie}</div>
        </DriftSection>
        <DriftSection
          title="Ideal (target) allocation"
          description="Target allocation defined in Drift Settings."
          icon={PieChartIcon}
        >
          <div className="p-4 sm:p-5">
            <DriftAllocationDonut
              data={idealDonutSource}
              config={idealDonutConfig}
              resolveColor={(row) => row.color ?? DRIFT_RULE_COLORS[0]}
            />
          </div>
        </DriftSection>
      </div>
    </div>
  );
}
