"use client";

import * as React from "react";
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Cell, Legend, Line, LineChart, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
import { cn } from "@/lib/utils";
import { fmtMoney, fmtNumber } from "@/lib/format";

export const CHART_COLORS = {
  primary: "var(--color-primary)",
  brand300: "var(--color-brand-300)",
  gold: "var(--color-gold-500)",
  positive: "var(--color-positive-500)",
  warning: "var(--color-warning-500)",
  negative: "var(--color-negative-500)",
  info: "var(--color-info-500)",
  accent: "var(--color-accent-500)",
  muted: "var(--color-stone-400)",
};
export const CATEGORICAL = ["#16786a", "#c9a24a", "#2563eb", "#7c3aed", "#d97706", "#dc2626", "#0891b2", "#78726b"];

function TooltipBox({ active, payload, label, money, formatter }: { active?: boolean; payload?: { name: string; value: number; color?: string; dataKey?: string; payload?: Record<string, unknown> }[]; label?: string; money?: boolean; formatter?: (v: number, name: string) => string }) {
  if (!active || !payload?.length) return null;
  return (
    <div className="rounded-md border border-border bg-surface px-3 py-2 text-xs shadow-lg">
      {label ? <p className="mb-1 font-medium text-fg">{label}</p> : null}
      {payload.map((p, i) => (
        <div key={i} className="flex items-center justify-between gap-4">
          <span className="flex items-center gap-1.5 text-fg-muted">
            <span className="size-2 rounded-sm" style={{ background: p.color ?? (p.payload?.fill as string) }} />
            {p.name}
          </span>
          <span className="font-medium tabular text-fg">{formatter ? formatter(p.value, p.name) : money ? fmtMoney(p.value) : fmtNumber(p.value)}</span>
        </div>
      ))}
    </div>
  );
}

const axisProps = { tickLine: false, axisLine: false, fontSize: 11, tick: { fill: "var(--color-fg-muted)" } } as const;
const compactMoney = (v: number) => (Math.abs(v) >= 1000 ? `${(v / 1000).toFixed(v % 1000 === 0 ? 0 : 1)}k` : String(v));

export interface Series {
  key: string;
  name: string;
  color?: string;
}

export function TrendChart({ data, series, xKey = "label", money = true, height = 260, type = "area", stacked, className }: { data: Record<string, unknown>[]; series: Series[]; xKey?: string; money?: boolean; height?: number; type?: "area" | "line" | "bar"; stacked?: boolean; className?: string }) {
  const id = React.useId();
  const Chart = type === "bar" ? BarChart : type === "line" ? LineChart : AreaChart;
  return (
    <div className={cn("w-full", className)} style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <Chart data={data} margin={{ top: 8, right: 8, left: -12, bottom: 0 }}>
          <defs>
            {series.map((s, i) => (
              <linearGradient key={s.key} id={`${id}-${i}`} x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor={s.color ?? CATEGORICAL[i]} stopOpacity={0.28} />
                <stop offset="100%" stopColor={s.color ?? CATEGORICAL[i]} stopOpacity={0} />
              </linearGradient>
            ))}
          </defs>
          <CartesianGrid vertical={false} strokeDasharray="3 3" />
          <XAxis dataKey={xKey} {...axisProps} interval="preserveStartEnd" minTickGap={24} />
          <YAxis {...axisProps} tickFormatter={money ? compactMoney : undefined} width={48} />
          <Tooltip content={<TooltipBox money={money} />} cursor={{ stroke: "var(--color-border-strong)", strokeDasharray: "3 3" }} />
          {series.length > 1 ? <Legend iconType="circle" iconSize={8} wrapperStyle={{ fontSize: 12, paddingTop: 8 }} /> : null}
          {series.map((s, i) =>
            type === "bar" ? (
              <Bar key={s.key} dataKey={s.key} name={s.name} fill={s.color ?? CATEGORICAL[i]} radius={[4, 4, 0, 0]} stackId={stacked ? "a" : undefined} maxBarSize={36} />
            ) : type === "line" ? (
              <Line key={s.key} type="monotone" dataKey={s.key} name={s.name} stroke={s.color ?? CATEGORICAL[i]} strokeWidth={2} dot={false} activeDot={{ r: 4 }} />
            ) : (
              <Area key={s.key} type="monotone" dataKey={s.key} name={s.name} stroke={s.color ?? CATEGORICAL[i]} strokeWidth={2} fill={`url(#${id}-${i})`} stackId={stacked ? "a" : undefined} activeDot={{ r: 4 }} />
            )
          )}
        </Chart>
      </ResponsiveContainer>
    </div>
  );
}

export function DonutChart({ data, height = 220, money, centerLabel, centerValue, className }: { data: { name: string; value: number; color?: string }[]; height?: number; money?: boolean; centerLabel?: string; centerValue?: string; className?: string }) {
  const total = data.reduce((s, d) => s + d.value, 0);
  return (
    <div className={cn("flex flex-col items-center gap-3 sm:flex-row", className)}>
      <div className="relative shrink-0" style={{ height, width: height }}>
        <ResponsiveContainer width="100%" height="100%">
          <PieChart>
            <Pie data={data} dataKey="value" nameKey="name" innerRadius="66%" outerRadius="92%" paddingAngle={2} stroke="none" cornerRadius={3}>
              {data.map((d, i) => (
                <Cell key={i} fill={d.color ?? CATEGORICAL[i % CATEGORICAL.length]} />
              ))}
            </Pie>
            <Tooltip content={<TooltipBox money={money} />} />
          </PieChart>
        </ResponsiveContainer>
        {centerValue ? (
          <div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center">
            <span className="text-lg font-semibold tabular text-fg">{centerValue}</span>
            {centerLabel ? <span className="text-2xs uppercase tracking-wider text-fg-muted">{centerLabel}</span> : null}
          </div>
        ) : null}
      </div>
      <ul className="grid w-full grid-cols-2 gap-x-4 gap-y-1.5 text-xs sm:grid-cols-1">
        {data.map((d, i) => (
          <li key={d.name} className="flex items-center justify-between gap-2">
            <span className="flex items-center gap-1.5 text-fg-muted min-w-0">
              <span className="size-2 shrink-0 rounded-sm" style={{ background: d.color ?? CATEGORICAL[i % CATEGORICAL.length] }} />
              <span className="truncate">{d.name}</span>
            </span>
            <span className="tabular font-medium text-fg shrink-0">
              {money ? fmtMoney(d.value, "MAD", { compact: true }) : fmtNumber(d.value)}
              <span className="ml-1 text-fg-subtle">{total ? Math.round((d.value / total) * 100) : 0}%</span>
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

export function HBarChart({ data, valueKey = "value", nameKey = "name", money, height, color = CHART_COLORS.primary, className, formatter }: { data: Record<string, unknown>[]; valueKey?: string; nameKey?: string; money?: boolean; height?: number; color?: string; className?: string; formatter?: (v: number, name: string) => string }) {
  const h = height ?? Math.max(120, data.length * 32 + 16);
  return (
    <div className={cn("w-full", className)} style={{ height: h }}>
      <ResponsiveContainer width="100%" height="100%">
        <BarChart data={data} layout="vertical" margin={{ top: 0, right: 16, left: 0, bottom: 0 }}>
          <CartesianGrid horizontal={false} strokeDasharray="3 3" />
          <XAxis type="number" {...axisProps} tickFormatter={money ? compactMoney : undefined} />
          <YAxis type="category" dataKey={nameKey} {...axisProps} width={72} />
          <Tooltip content={<TooltipBox money={money} formatter={formatter} />} cursor={{ fill: "var(--color-surface-2)" }} />
          <Bar dataKey={valueKey} fill={color} radius={[0, 4, 4, 0]} maxBarSize={18} />
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}
