"use client";

import type { ReactElement, ReactNode } from "react";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import {
  Bar,
  BarChart,
  Cell,
  Label,
  Pie,
  PieChart,
  PolarAngleAxis,
  RadialBar,
  RadialBarChart,
  XAxis,
  YAxis,
} from "recharts";

import { Card, CardContent } from "@/components/ui/card";
import {
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/components/ui/chart";
import { cn } from "@/lib/utils";
import {
  buildBatchProgressConfig,
  buildFinanceStructureConfig,
  buildPayoutPieConfig,
  buildSoldOutPieConfig,
  buildSettlementBarConfig,
  buildUsageBarConfig,
  DASHBOARD_CHART_COLORS,
} from "@/modules/dashboard/dashboard-chart-config";
import { DashboardChartEmpty } from "@/modules/dashboard/dashboard-chart-empty";
import type { AdminDrawFinanceSummaryData } from "@/types/api/admin-draw-finance";
import type { AdminRiskPoolRow } from "@/types/api/admin-risk";
import type {
  AdminDashboardDrawPanel,
  AdminDashboardSoldOutBuckets,
} from "@/types/api/admin-dashboard";

export type SoldOutBuckets = AdminDashboardSoldOutBuckets;

type MoneyFormatter = (minor: number, currency: string | null) => string;

function usageBarFill(pct: number): string {
  if (pct >= 95) {
    return DASHBOARD_CHART_COLORS.rose;
  }
  if (pct >= 80) {
    return DASHBOARD_CHART_COLORS.warning;
  }
  return DASHBOARD_CHART_COLORS.primary;
}

function capUsageFill(pct: number): string {
  if (pct >= 90) {
    return "var(--destructive)";
  }
  if (pct >= 70) {
    return DASHBOARD_CHART_COLORS.warning;
  }
  return DASHBOARD_CHART_COLORS.primary;
}

function settlementBarColor(status: string): string {
  switch (status) {
    case "pending_review":
      return DASHBOARD_CHART_COLORS.warning;
    case "approved":
      return "oklch(0.62 0.14 230)";
    case "paid":
    case "completed":
      return DASHBOARD_CHART_COLORS.success;
    case "running":
      return DASHBOARD_CHART_COLORS.primary;
    case "rejected":
    case "failed":
      return DASHBOARD_CHART_COLORS.rose;
    default:
      return DASHBOARD_CHART_COLORS.violet;
  }
}

export function StatCard({
  label,
  value,
  hint,
  icon,
  accent = "primary",
}: {
  label: string;
  value: ReactNode;
  hint?: ReactNode;
  icon: ReactNode;
  accent?: "primary" | "destructive" | "muted";
}): ReactElement {
  const accentClass =
    accent === "destructive"
      ? "bg-destructive text-destructive-foreground"
      : accent === "muted"
        ? "bg-muted text-foreground"
        : "bg-primary text-primary-foreground";

  return (
    <Card className="border-border/80 py-0 shadow-sm">
      <CardContent className="flex gap-4 p-5">
        <div
          className={cn(
            "flex size-11 shrink-0 items-center justify-center rounded-lg shadow-sm",
            accentClass,
          )}
        >
          {icon}
        </div>
        <div className="min-w-0 flex-1">
          <p className="text-sm font-medium text-muted-foreground">{label}</p>
          <p className="mt-1 text-2xl font-bold tabular-nums tracking-tight text-foreground">{value}</p>
          {hint ? <div className="mt-2 text-xs text-muted-foreground">{hint}</div> : null}
        </div>
      </CardContent>
    </Card>
  );
}

export function CapUsageBar({
  locked,
  cap,
  usagePct,
  formatMoney,
  currency,
}: {
  locked: number;
  cap: number;
  usagePct: number;
  formatMoney: MoneyFormatter;
  currency: string | null;
}): ReactElement {
  const { t } = useTranslation("dashboard");
  const pct = Math.min(100, Math.max(0, usagePct));
  const fill = capUsageFill(pct);
  const chartConfig = useMemo(
    () => buildUsageBarConfig(t("riskCapUsage")),
    [t],
  );
  const radialData = useMemo(() => [{ usage: pct, fill }], [pct, fill]);

  return (
    <div className="space-y-4">
      <ChartContainer
        config={chartConfig}
        className="mx-auto aspect-square h-[180px] w-full max-w-[200px]"
      >
        <RadialBarChart
          data={radialData}
          startAngle={90}
          endAngle={-270}
          innerRadius="72%"
          outerRadius="100%"
        >
          <PolarAngleAxis type="number" domain={[0, 100]} tick={false} />
          <RadialBar
            dataKey="usage"
            background={{ fill: "var(--muted)" }}
            cornerRadius={8}
            fill={fill}
          />
          <Label
            content={({ viewBox }) => {
              if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) {
                return null;
              }
              const { cx, cy } = viewBox as { cx: number; cy: number };
              return (
                <text x={cx} y={cy} textAnchor="middle" dominantBaseline="middle">
                  <tspan className="fill-foreground text-2xl font-bold">{pct.toFixed(1)}%</tspan>
                </text>
              );
            }}
          />
        </RadialBarChart>
      </ChartContainer>
      <p className="text-center text-xs tabular-nums text-muted-foreground">
        {t("lockedAndCap", {
          locked: formatMoney(locked, currency),
          cap: formatMoney(cap, currency),
        })}
      </p>
    </div>
  );
}

export function FinanceStructureChart({
  finance,
  formatMoney,
}: {
  finance: AdminDrawFinanceSummaryData;
  formatMoney: MoneyFormatter;
}): ReactElement {
  const { t } = useTranslation("dashboard");
  const currency = finance.currency_code;
  const bet = finance.total_bet_minor;
  const win = finance.total_win_payout_minor;
  const jackpot = finance.total_jackpot_win_minor;
  const gross = finance.approx_house_gross_minor;
  const payout = finance.total_payout_minor;

  const chartConfig = useMemo(
    () =>
      buildFinanceStructureConfig({
        win: t("winPayout"),
        jackpot: t("jackpotPayout"),
        gross: t("houseGross"),
      }),
    [t],
  );

  if (bet <= 0) {
    return <DashboardChartEmpty message={t("noFinanceActivity")} />;
  }

  const payoutRate = ((payout / bet) * 100).toFixed(1);
  const chartData = [{ segment: "structure", win, jackpot, gross }];

  return (
    <div className="space-y-4">
      <ChartContainer config={chartConfig} className="aspect-auto h-12 w-full">
        <BarChart
          accessibilityLayer
          layout="vertical"
          data={chartData}
          margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
        >
          <XAxis type="number" hide domain={[0, bet]} />
          <YAxis type="category" dataKey="segment" hide width={0} />
          <ChartTooltip
            content={
              <ChartTooltipContent formatter={(value, _name) => formatMoney(Number(value), currency)} />
            }
          />
          <Bar dataKey="win" stackId="structure" fill="var(--color-win)" radius={4} />
          <Bar dataKey="jackpot" stackId="structure" fill="var(--color-jackpot)" radius={4} />
          <Bar dataKey="gross" stackId="structure" fill="var(--color-gross)" radius={4} />
        </BarChart>
      </ChartContainer>
      <p className="text-center text-xs text-muted-foreground">
        {t("payoutRateOfBet", { rate: payoutRate })}
      </p>
      <ChartLegend content={<ChartLegendContent />} />
    </div>
  );
}

export function PayoutCompositionChart({
  finance,
  formatMoney,
}: {
  finance: AdminDrawFinanceSummaryData;
  formatMoney: MoneyFormatter;
}): ReactElement {
  const { t } = useTranslation("dashboard");
  const currency = finance.currency_code;
  const win = finance.total_win_payout_minor;
  const jackpot = finance.total_jackpot_win_minor;
  const total = win + jackpot;

  const chartConfig = useMemo(
    () =>
      buildPayoutPieConfig({
        win: t("winPayout"),
        jackpot: t("jackpotPayout"),
      }),
    [t],
  );

  if (total <= 0) {
    return <DashboardChartEmpty message={t("noPayoutYet")} />;
  }

  const pieData = [
    { key: "win", value: win, fill: "var(--color-win)" },
    { key: "jackpot", value: jackpot, fill: "var(--color-jackpot)" },
  ];

  return (
    <ChartContainer config={chartConfig} className="mx-auto aspect-square h-[220px] w-full max-w-[280px]">
      <PieChart>
        <ChartTooltip
          content={
            <ChartTooltipContent
              nameKey="key"
              formatter={(value) => formatMoney(Number(value), currency)}
            />
          }
        />
        <Pie
          data={pieData}
          dataKey="value"
          nameKey="key"
          innerRadius="58%"
          outerRadius="82%"
          paddingAngle={2}
        >
          {pieData.map((entry) => (
            <Cell key={entry.key} fill={entry.fill} />
          ))}
        </Pie>
        <ChartLegend content={<ChartLegendContent nameKey="key" />} />
      </PieChart>
    </ChartContainer>
  );
}

export function HotUsageBars({ rows }: { rows: AdminRiskPoolRow[] }): ReactElement {
  const { t } = useTranslation("dashboard");
  const chartConfig = useMemo(() => buildUsageBarConfig(t("riskCapUsage")), [t]);

  const chartData = useMemo(
    () =>
      rows.map((row) => {
        const pct = Math.min(100, Math.max(0, (row.usage_ratio ?? 0) * 100));
        return {
          number: row.normalized_number.trim(),
          usage: pct,
          fill: usageBarFill(pct),
        };
      }),
    [rows],
  );

  if (rows.length === 0) {
    return <DashboardChartEmpty message={t("noPoolData")} />;
  }

  const chartHeight = Math.min(420, Math.max(160, rows.length * 32 + 48));

  return (
    <ChartContainer
      config={chartConfig}
      className="aspect-auto w-full"
      style={{ height: chartHeight }}
    >
      <BarChart
        accessibilityLayer
        layout="vertical"
        data={chartData}
        margin={{ top: 4, right: 12, bottom: 4, left: 4 }}
      >
        <XAxis type="number" domain={[0, 100]} hide />
        <YAxis
          type="category"
          dataKey="number"
          width={72}
          tickLine={false}
          axisLine={false}
          tick={{ fontSize: 11, fontFamily: "var(--font-mono)" }}
        />
        <ChartTooltip
          content={
            <ChartTooltipContent
              formatter={(value) => `${Number(value).toFixed(1)}%`}
            />
          }
        />
        <Bar dataKey="usage" radius={4} barSize={14}>
          {chartData.map((entry) => (
            <Cell key={entry.number} fill={entry.fill} />
          ))}
        </Bar>
      </BarChart>
    </ChartContainer>
  );
}

export function SoldOutRing({ buckets }: { buckets: SoldOutBuckets }): ReactElement {
  const { t } = useTranslation("dashboard");

  const chartConfig = useMemo(
    () =>
      buildSoldOutPieConfig({
        d4: t("soldOutBuckets.d4"),
        d3: t("soldOutBuckets.d3"),
        d2: t("soldOutBuckets.d2"),
        special: t("soldOutBuckets.special"),
        other: t("soldOutBuckets.other"),
      }),
    [t],
  );

  const entries: (keyof SoldOutBuckets)[] = ["d4", "d3", "d2", "special", "other"];
  const total = entries.reduce((s, key) => s + buckets[key], 0);

  if (total === 0) {
    return <DashboardChartEmpty message={t("noSoldOutNumbers")} />;
  }

  const pieData = entries
    .filter((key) => buckets[key] > 0)
    .map((key) => ({
      key,
      value: buckets[key],
      fill: `var(--color-${key})`,
    }));

  return (
    <ChartContainer config={chartConfig} className="mx-auto aspect-square h-[240px] w-full max-w-[320px]">
      <PieChart>
        <ChartTooltip content={<ChartTooltipContent nameKey="key" />} />
        <Pie
          data={pieData}
          dataKey="value"
          nameKey="key"
          innerRadius="58%"
          outerRadius="82%"
          paddingAngle={2}
        >
          {pieData.map((entry) => (
            <Cell key={entry.key} fill={entry.fill} />
          ))}
          <Label
            content={({ viewBox }) => {
              if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) {
                return null;
              }
              const { cx, cy } = viewBox as { cx: number; cy: number };
              return (
                <text x={cx} y={cy} textAnchor="middle" dominantBaseline="middle">
                  <tspan className="fill-foreground text-3xl font-bold">{total}</tspan>
                  <tspan x={cx} dy="1.4em" className="fill-muted-foreground text-xs">
                    {t("soldOutTotal")}
                  </tspan>
                </text>
              );
            }}
          />
        </Pie>
        <ChartLegend content={<ChartLegendContent nameKey="key" />} />
      </PieChart>
    </ChartContainer>
  );
}

export function ResultBatchProgress({ draw }: { draw: AdminDashboardDrawPanel }): ReactElement {
  const { t } = useTranslation("dashboard");
  const { total, pending_review, published } = draw.result_batch_counts;
  const other = Math.max(0, total - pending_review - published);

  const chartConfig = useMemo(
    () =>
      buildBatchProgressConfig({
        pending: t("batchPending"),
        published: t("batchPublished"),
        other: t("batchOther"),
      }),
    [t],
  );

  const chartData = [{ row: "batches", pending: pending_review, published, other }];

  return (
    <div className="space-y-4">
      <ChartContainer config={chartConfig} className="aspect-auto h-10 w-full">
        <BarChart
          accessibilityLayer
          layout="vertical"
          data={chartData}
          margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
        >
          <XAxis type="number" hide domain={[0, Math.max(total, 1)]} />
          <YAxis type="category" dataKey="row" hide width={0} />
          <Bar dataKey="pending" stackId="batch" fill="var(--color-pending)" radius={4} />
          <Bar dataKey="published" stackId="batch" fill="var(--color-published)" radius={4} />
          <Bar dataKey="other" stackId="batch" fill="var(--color-other)" radius={4} />
        </BarChart>
      </ChartContainer>
      <div className="grid grid-cols-3 gap-2 text-center">
        <div className="rounded-lg border border-border/60 bg-muted/20 px-2 py-3">
          <p className="text-2xl font-bold tabular-nums text-amber-600">{pending_review}</p>
          <p className="mt-1 text-xs text-muted-foreground">{t("batchPending")}</p>
        </div>
        <div className="rounded-lg border border-border/60 bg-muted/20 px-2 py-3">
          <p className="text-2xl font-bold tabular-nums text-emerald-600">{published}</p>
          <p className="mt-1 text-xs text-muted-foreground">{t("batchPublished")}</p>
        </div>
        <div className="rounded-lg border border-border/60 bg-muted/20 px-2 py-3">
          <p className="text-2xl font-bold tabular-nums">{total}</p>
          <p className="mt-1 text-xs text-muted-foreground">{t("batchTotal")}</p>
        </div>
      </div>
    </div>
  );
}

export function SettlementStatusChart({
  finance,
}: {
  finance: AdminDrawFinanceSummaryData;
}): ReactElement {
  const { t } = useTranslation("dashboard");
  const settlementBatches = finance.settlement_batches;

  const entries = useMemo(() => {
    const counts = new Map<string, number>();
    for (const b of settlementBatches ?? []) {
      counts.set(b.status, (counts.get(b.status) ?? 0) + 1);
    }
    return [...counts.entries()].sort((a, b) => b[1] - a[1]);
  }, [settlementBatches]);

  const chartConfig = useMemo(
    (): ChartConfig =>
      buildSettlementBarConfig(
        entries.map(([status]) => ({
          status,
          label: status,
          color: settlementBarColor(status),
        })),
      ),
    [entries],
  );

  if (!settlementBatches || settlementBatches.length === 0) {
    return <DashboardChartEmpty message={t("noSettlementBatches")} />;
  }

  const chartData = entries.map(([status, count]) => ({
    status,
    count,
    fill: settlementBarColor(status),
  }));

  const chartHeight = Math.min(360, Math.max(140, entries.length * 40 + 40));

  return (
    <ChartContainer
      config={chartConfig}
      className="aspect-auto w-full"
      style={{ height: chartHeight }}
    >
      <BarChart
        accessibilityLayer
        layout="vertical"
        data={chartData}
        margin={{ top: 4, right: 12, bottom: 4, left: 8 }}
      >
        <XAxis type="number" hide />
        <YAxis
          type="category"
          dataKey="status"
          width={108}
          tickLine={false}
          axisLine={false}
          tick={{ fontSize: 11 }}
        />
        <ChartTooltip content={<ChartTooltipContent />} />
        <Bar dataKey="count" radius={4} barSize={16}>
          {chartData.map((entry) => (
            <Cell key={entry.status} fill={entry.fill} />
          ))}
        </Bar>
      </BarChart>
    </ChartContainer>
  );
}
