"use client";

import type { ReactElement, ReactNode } from "react";
import { useTranslation } from "react-i18next";

import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
import { cn } from "@/lib/utils";
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;

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 (
    <div className="rounded-xl border border-border/80 bg-card p-5 shadow-sm">
      <div className="flex gap-4">
        <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>
      </div>
    </div>
  );
}

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

  return (
    <div className="space-y-3">
      <div className="flex items-end justify-between gap-2">
        <span className="text-sm font-medium text-foreground">{t("riskCapUsage")}</span>
        <span className="text-2xl font-bold tabular-nums text-foreground">{pct.toFixed(1)}%</span>
      </div>
      <div className="h-3 overflow-hidden rounded-full bg-muted">
        <div
          className={cn(
            "h-full rounded-full transition-all duration-500",
            pct >= 90 ? "bg-destructive" : pct >= 70 ? "bg-amber-500" : "bg-primary",
          )}
          style={{ width: `${pct}%` }}
        />
      </div>
      <p className="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 payout = finance.total_payout_minor;
  const gross = finance.approx_house_gross_minor;

  if (bet <= 0) {
    return <p className="py-8 text-center text-sm text-muted-foreground">{t("noFinanceActivity")}</p>;
  }

  const winW = (win / bet) * 100;
  const jpW = (jackpot / bet) * 100;
  const grossW = Math.max(0, (gross / bet) * 100);
  const payoutRate = ((payout / bet) * 100).toFixed(1);

  const segments = [
    { key: "win", width: winW, className: "bg-emerald-500", label: t("winPayout"), value: win },
    { key: "jackpot", width: jpW, className: "bg-violet-500", label: t("jackpotPayout"), value: jackpot },
    { key: "gross", width: grossW, className: "bg-primary", label: t("houseGross"), value: gross },
  ].filter((s) => s.width > 0.05);

  return (
    <div className="space-y-4">
      <div className="flex h-10 overflow-hidden rounded-lg ring-1 ring-border/60">
        {segments.map((s) => (
          <div
            key={s.key}
            className={cn("min-w-[2px] transition-all", s.className)}
            style={{ width: `${s.width}%` }}
            title={`${s.label}: ${formatMoney(s.value, currency)}`}
          />
        ))}
      </div>
      <p className="text-center text-xs text-muted-foreground">
        {t("payoutRateOfBet", { rate: payoutRate })}
      </p>
      <ul className="grid gap-2 sm:grid-cols-3">
        {segments.map((s) => (
          <li key={s.key} className="flex items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-3 py-2">
            <span className={cn("size-2.5 shrink-0 rounded-sm", s.className)} />
            <div className="min-w-0">
              <p className="text-xs text-muted-foreground">{s.label}</p>
              <p className="truncate text-sm font-semibold tabular-nums">{formatMoney(s.value, currency)}</p>
            </div>
          </li>
        ))}
      </ul>
    </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;

  if (total <= 0) {
    return <p className="py-8 text-center text-sm text-muted-foreground">{t("noPayoutYet")}</p>;
  }

  const winPct = (win / total) * 100;
  const winColor = "oklch(0.62 0.17 162)";
  const jackpotColor = "oklch(0.56 0.22 303)";
  const items = [
    { label: t("winPayout"), value: win, pct: winPct, className: "bg-emerald-500", color: winColor },
    {
      label: t("jackpotPayout"),
      value: jackpot,
      pct: 100 - winPct,
      className: "bg-violet-500",
      color: jackpotColor,
    },
  ];

  return (
    <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
      <div
        className="relative mx-auto size-36 shrink-0 rounded-full"
        style={{
          background: `conic-gradient(from -90deg, ${winColor} 0deg ${winPct * 3.6}deg, ${jackpotColor} ${winPct * 3.6}deg 360deg)`,
          mask: "radial-gradient(farthest-side, transparent 58%, #000 59%)",
          WebkitMask: "radial-gradient(farthest-side, transparent 58%, #000 59%)",
        }}
      />
      <ul className="min-w-0 flex-1 space-y-3">
        {items.map((item) => (
          <li key={item.label}>
            <div className="mb-1 flex justify-between gap-2 text-sm">
              <span className="flex items-center gap-2 text-muted-foreground">
                <span className={cn("size-2.5 rounded-sm", item.className)} />
                {item.label}
              </span>
              <span className="font-medium tabular-nums">{item.pct.toFixed(1)}%</span>
            </div>
            <p className="text-sm font-semibold tabular-nums">{formatMoney(item.value, currency)}</p>
            <div className="mt-1.5 h-1.5 overflow-hidden rounded-full bg-muted">
              <div
                className="h-full rounded-full"
                style={{ width: `${item.pct}%`, background: item.color }}
              />
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

export function HotUsageBars({ rows }: { rows: AdminRiskPoolRow[] }): ReactElement {
  const { t } = useTranslation("dashboard");

  if (rows.length === 0) {
    return <p className="py-10 text-center text-sm text-muted-foreground">{t("noPoolData")}</p>;
  }

  return (
    <ul className="space-y-2.5">
      {rows.map((row) => {
        const pct = Math.min(100, Math.max(0, (row.usage_ratio ?? 0) * 100));
        return (
          <li key={row.normalized_number}>
            <div className="mb-1 flex items-center justify-between gap-2 text-xs">
              <span className="truncate font-mono font-medium text-foreground">
                {row.normalized_number.trim()}
              </span>
              <span className="shrink-0 tabular-nums text-muted-foreground">{pct.toFixed(1)}%</span>
            </div>
            <div className="h-2 overflow-hidden rounded-full bg-muted">
              <div
                className={cn(
                  "h-full rounded-full transition-all",
                  pct >= 95 ? "bg-destructive" : pct >= 80 ? "bg-amber-500" : "bg-primary",
                )}
                style={{ width: `${pct}%` }}
              />
            </div>
          </li>
        );
      })}
    </ul>
  );
}

export function SoldOutRing({ buckets }: { buckets: SoldOutBuckets }): ReactElement {
  const { t } = useTranslation("dashboard");
  const entries: { key: keyof SoldOutBuckets; label: string; color: string; swatch: string }[] = [
    { key: "d4", label: t("soldOutBuckets.d4"), color: "oklch(0.52 0.19 264)", swatch: "bg-blue-600" },
    { key: "d3", label: t("soldOutBuckets.d3"), color: "oklch(0.62 0.17 162)", swatch: "bg-emerald-500" },
    { key: "d2", label: t("soldOutBuckets.d2"), color: "oklch(0.72 0.16 75)", swatch: "bg-amber-500" },
    { key: "special", label: t("soldOutBuckets.special"), color: "oklch(0.56 0.22 303)", swatch: "bg-violet-500" },
    { key: "other", label: t("soldOutBuckets.other"), color: "oklch(0.58 0.2 25)", swatch: "bg-rose-500" },
  ];
  const total = entries.reduce((s, e) => s + buckets[e.key], 0);

  if (total === 0) {
    return <p className="py-10 text-center text-sm text-muted-foreground">{t("noSoldOutNumbers")}</p>;
  }

  let acc = 0;
  const parts = entries
    .filter((e) => buckets[e.key] > 0)
    .map((e) => {
      const frac = buckets[e.key] / total;
      const start = acc;
      acc += frac;
      return { ...e, frac, start };
    });

  const gradientStops =
    parts.length === 1
      ? `${parts[0].color} 0deg 360deg`
      : parts
          .map((p) => {
            const a0 = p.start * 360;
            const a1 = (p.start + p.frac) * 360;
            return `${p.color} ${a0}deg ${a1}deg`;
          })
          .join(", ");

  return (
    <div className="flex flex-col items-stretch gap-4 sm:flex-row sm:items-center">
      <div className="relative mx-auto size-40 shrink-0">
        <div
          className="size-full rounded-full"
          style={{
            background: `conic-gradient(from -90deg, ${gradientStops})`,
            mask: "radial-gradient(farthest-side, transparent 58%, #000 59%)",
            WebkitMask: "radial-gradient(farthest-side, transparent 58%, #000 59%)",
          }}
        />
        <div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center">
          <p className="text-3xl font-bold tabular-nums">{total}</p>
          <p className="text-xs text-muted-foreground">{t("soldOutTotal")}</p>
        </div>
      </div>
      <ul className="min-w-0 flex-1 space-y-2">
        {entries.map((e) => {
          const count = buckets[e.key];
          const pct = total > 0 ? (count / total) * 100 : 0;
          return (
            <li key={e.key}>
              <div className="mb-1 flex justify-between text-sm">
                <span className="flex items-center gap-2 text-muted-foreground">
                  <span className={cn("size-2.5 rounded-sm", e.swatch)} />
                  {e.label}
                </span>
                <span className="font-medium tabular-nums">
                  {count}
                  <span className="ml-1 text-xs font-normal text-muted-foreground">({pct.toFixed(0)}%)</span>
                </span>
              </div>
              <div className="h-1.5 overflow-hidden rounded-full bg-muted">
                <div className="h-full rounded-full" style={{ width: `${pct}%`, background: e.color }} />
              </div>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

export function ResultBatchProgress({ draw }: { draw: AdminDashboardDrawPanel }): ReactElement {
  const { t } = useTranslation("dashboard");
  const { total, pending_review, published } = draw.result_batch_counts;
  const pendingW = total > 0 ? (pending_review / total) * 100 : 0;
  const publishedW = total > 0 ? (published / total) * 100 : 0;
  const otherW = Math.max(0, 100 - pendingW - publishedW);

  return (
    <div className="space-y-4">
      <div className="flex h-3 overflow-hidden rounded-full bg-muted">
        {pendingW > 0 ? (
          <div className="bg-amber-500" style={{ width: `${pendingW}%` }} title={t("batchPending")} />
        ) : null}
        {publishedW > 0 ? (
          <div className="bg-emerald-600" style={{ width: `${publishedW}%` }} title={t("batchPublished")} />
        ) : null}
        {otherW > 0 ? <div className="bg-muted-foreground/30" style={{ width: `${otherW}%` }} /> : null}
      </div>
      <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 batches = finance.settlement_batches ?? [];

  if (batches.length === 0) {
    return <p className="py-6 text-center text-sm text-muted-foreground">{t("noSettlementBatches")}</p>;
  }

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

  const barTone = (status: string): string => {
    switch (status) {
      case "pending_review":
        return "bg-amber-500";
      case "approved":
        return "bg-sky-500";
      case "paid":
      case "completed":
        return "bg-emerald-600";
      case "running":
        return "bg-blue-500";
      case "rejected":
      case "failed":
        return "bg-rose-500";
      default:
        return "bg-violet-500";
    }
  };

  return (
    <ul className="space-y-3">
      {entries.map(([status, count]) => (
        <li key={status}>
          <div className="mb-1 flex items-center justify-between gap-2">
            <AdminStatusBadge status={status}>{status}</AdminStatusBadge>
            <span className="text-sm font-medium tabular-nums">{count}</span>
          </div>
          <div className="h-2 overflow-hidden rounded-full bg-muted">
            <div
              className={cn("h-full rounded-full transition-all", barTone(status))}
              style={{ width: `${max > 0 ? (count / max) * 100 : 0}%` }}
            />
          </div>
        </li>
      ))}
    </ul>
  );
}
