"use client";

import Image from "next/image";
import Link from "next/link";
import type { ReactNode } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import {
  ArrowLeft,
  BarChart3,
  Check,
  ChevronDown,
  Copy,
  Gauge,
  Infinity,
  Loader2,
  Rocket,
  Settings,
  Sparkles,
  Star,
  Target,
  X
} from "lucide-react";
import { CasinoStakeInput } from "@/components/casino/casino-stake-input";
import { GameDetailsPanel } from "@/components/casino/game-details-panel";
import { formatAmountInput, formatAmountInputFixed, parseAmountInput, parseDecimalInput } from "@/lib/amount-input";
import { notifyWalletUpdated } from "@/lib/client-events";
import { miniGames } from "@/lib/casino-games";
import { cn } from "@/lib/utils";
import { StakeLimitNote } from "@/components/casino/stake-limit-note";

type LimboRound = {
  id: string;
  currency: string;
  stake: string;
  payout: string;
  profit: string;
  multiplier: string;
  chance: string;
  target: string;
  direction: string;
  result: string;
  nonce: number;
  status: "WON" | "LOST" | "VOID";
  serverSeedHash: string;
  createdAt: string;
};

type LimboState = {
  config: {
    minStake: string;
    maxStake: string;
    maxPayout: string;
    minMultiplier: number;
    maxMultiplier: number;
    houseEdgeBps: number;
  };
  currency: string;
  seedPair: {
    id: string;
    clientSeed: string;
    serverSeedHash: string;
    nonce: number;
  };
  stats: {
    stake: string;
    profit: string;
    wins: number;
    losses: number;
  };
  recentRounds: LimboRound[];
};

type Mode = "manual" | "auto";

const DEFAULT_STATE: LimboState = {
  config: {
    minStake: "0.01",
    maxStake: "10000",
    maxPayout: "100000",
    minMultiplier: 1.01,
    maxMultiplier: 1000000,
    houseEdgeBps: 100
  },
  currency: "EUR",
  seedPair: {
    id: "",
    clientSeed: "",
    serverSeedHash: "",
    nonce: 0
  },
  stats: {
    stake: "0",
    profit: "0",
    wins: 0,
    losses: 0
  },
  recentRounds: []
};

export function LimboGame() {
  const [state, setState] = useState<LimboState>(DEFAULT_STATE);
  const [loading, setLoading] = useState(true);
  const [guest, setGuest] = useState(false);
  const [message, setMessage] = useState("");
  const [mode, setMode] = useState<Mode>("manual");
  const [targetMultiplier, setTargetMultiplier] = useState("2.00");
  const [stake, setStake] = useState("0");
  const [betCount, setBetCount] = useState("0");
  const [lastRound, setLastRound] = useState<LimboRound | null>(null);
  const [displayMultiplier, setDisplayMultiplier] = useState(1);
  const [rolling, setRolling] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [statsOpen, setStatsOpen] = useState(false);
  const [fairnessOpen, setFairnessOpen] = useState(false);
  const [turbo, setTurbo] = useState(false);
  const [maxBet, setMaxBet] = useState(false);
  const [silent, setSilent] = useState(false);
  const [clientSeedInput, setClientSeedInput] = useState("");
  const [revealedSeed, setRevealedSeed] = useState<null | { serverSeed: string; clientSeed: string; nonce: number; serverSeedHash: string }>(null);
  const [verifyInput, setVerifyInput] = useState({ serverSeed: "", clientSeed: "", nonce: "" });
  const [verifyResult, setVerifyResult] = useState<null | { serverSeedHash: string; result: string }>(null);
  const autoStopRef = useRef(false);

  const target = useMemo(() => {
    const value = parseDecimalInput(targetMultiplier, 2);
    return Math.min(state.config.maxMultiplier, Math.max(state.config.minMultiplier, value));
  }, [targetMultiplier, state.config.maxMultiplier, state.config.minMultiplier]);

  const chance = useMemo(() => round8((100 - state.config.houseEdgeBps / 100) / target), [target, state.config.houseEdgeBps]);
  const potentialProfit = useMemo(() => {
    const amount = parseAmountInput(stake);
    return amount > 0 ? amount * target - amount : 0;
  }, [stake, target]);
  const otherGames = miniGames.filter((game) => game.slug !== "limbo");

  useEffect(() => {
    void loadState();
  }, []);

  useEffect(() => {
    if (!rolling) return;
    let frame = 0;
    const id = window.setInterval(() => {
      frame += 1;
      const speed = turbo ? 0.36 : 0.18;
      const simulated = 1 + Math.log1p(frame * speed) * Math.max(0.8, Math.min(target, 12)) * 0.14;
      setDisplayMultiplier(Number(simulated.toFixed(2)));
    }, 42);
    return () => window.clearInterval(id);
  }, [rolling, target, turbo]);

  async function loadState() {
    try {
      const response = await fetch("/api/casino/limbo/state", { cache: "no-store" });
      const payload = await response.json();
      if (!response.ok || !payload.ok) {
        const unauthenticated = response.status === 401 || payload.error?.code === "UNAUTHORIZED";
        setGuest(unauthenticated);
        setMessage(unauthenticated ? "Connecte-toi pour jouer à Limbo." : payload.error?.message ?? "Limbo indisponible.");
        return;
      }
      setState(payload.data);
      setClientSeedInput(payload.data.seedPair.clientSeed);
      setDisplayMultiplier(Number(payload.data.recentRounds[0]?.result ?? 1));
      setLastRound(payload.data.recentRounds[0] ?? null);
    } catch {
      setMessage("Impossible de charger Limbo pour le moment.");
    } finally {
      setLoading(false);
    }
  }

  async function placeRound() {
    if (guest) {
      window.location.href = "/login";
      return null;
    }

    const amount = parseAmountInput(stake);
    if (amount <= 0) {
      setMessage("Saisis une mise valide.");
      return null;
    }

    setMessage("");
    setRolling(true);
    setDisplayMultiplier(1);
    const startedAt = Date.now();

    try {
      const response = await fetch("/api/casino/limbo/play", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          currency: state.currency,
          stake: amount,
          multiplier: target,
          clientRequestId: crypto.randomUUID()
        })
      });
      const payload = await response.json();
      const elapsed = Date.now() - startedAt;
      if (elapsed < 520 && !turbo) {
        await wait(520 - elapsed);
      }

      if (!response.ok || !payload.ok) {
        setMessage(payload.error?.message ?? "Pari refusé.");
        return null;
      }

      const round: LimboRound = payload.data.round;
      setLastRound(round);
      setDisplayMultiplier(Number(round.result));
      setState((current) => ({
        ...current,
        seedPair: { ...current.seedPair, nonce: current.seedPair.nonce + 1 },
        stats: {
          stake: String(Number(current.stats.stake) + Number(round.stake)),
          profit: String(Number(current.stats.profit) + Number(round.profit)),
          wins: current.stats.wins + (round.status === "WON" ? 1 : 0),
          losses: current.stats.losses + (round.status === "LOST" ? 1 : 0)
        },
        recentRounds: [round, ...current.recentRounds].slice(0, 25)
      }));
      notifyWalletUpdated();
      if (!silent) {
        setMessage(round.status === "WON" ? `Gain ${formatMoney(round.payout, round.currency)}` : `Sorti à ${Number(round.result).toFixed(2)}x.`);
      }
      return round;
    } catch {
      setMessage("Erreur réseau pendant le pari.");
      return null;
    } finally {
      setRolling(false);
    }
  }

  async function startAuto() {
    autoStopRef.current = false;
    const limit = Number(betCount);
    let played = 0;
    setMessage("");

    while (!autoStopRef.current && (limit <= 0 || played < limit)) {
      const round = await placeRound();
      if (!round) break;
      played += 1;
      await wait(turbo ? 120 : 620);
    }
  }

  function stopAuto() {
    autoStopRef.current = true;
  }

  async function rotateSeeds() {
    setMessage("");
    try {
      const response = await fetch("/api/casino/limbo/seeds/rotate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ clientSeed: clientSeedInput })
      });
      const payload = await response.json();
      if (!response.ok || !payload.ok) {
        setMessage(payload.error?.message ?? "Rotation impossible.");
        return;
      }

      setRevealedSeed(payload.data.previous);
      setState((current) => ({
        ...current,
        seedPair: payload.data.current
      }));
      setClientSeedInput(payload.data.current.clientSeed);
      setMessage("Nouvelle paire de seeds active.");
    } catch {
      setMessage("Rotation des seeds indisponible.");
    }
  }

  async function verifySeed() {
    try {
      const response = await fetch("/api/casino/limbo/verify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(verifyInput)
      });
      const payload = await response.json();
      if (!response.ok || !payload.ok) {
        setMessage(payload.error?.message ?? "Vérification impossible.");
        return;
      }
      setVerifyResult(payload.data);
    } catch {
      setMessage("Vérification indisponible.");
    }
  }

  function halveStake() {
    setStake(formatInputAmount(parseAmountInput(stake) / 2));
  }

  function doubleStake() {
    setStake(formatInputAmount(parseAmountInput(stake) * 2));
  }

  if (loading) {
    return (
      <section className="grid min-h-[360px] place-items-center rounded-lg border border-white/10 bg-[#111720]">
        <Loader2 className="h-7 w-7 animate-spin text-felt" />
      </section>
    );
  }

  return (
    <div className="space-y-3.5">
      <div className="flex items-center gap-2">
        <Link href="/casino" className="grid h-9 w-9 place-items-center rounded-lg border border-white/10 bg-white/[0.04] text-slate-200">
          <ArrowLeft className="h-4 w-4" />
        </Link>
        <div className="flex h-9 items-center gap-2 rounded-lg bg-white/[0.055] px-3 text-sm font-black text-felt">
          <Target className="h-4 w-4" />
          Limbo
        </div>
      </div>

      <section className="overflow-hidden rounded-lg border border-white/10 bg-[#0e1219] shadow-panel">
        <div className="relative border-b border-white/10 bg-[#11161f] px-3 pb-4 pt-3 sm:px-4">
          <div className="mb-3 flex items-center gap-1.5 overflow-x-auto pb-1 scrollbar-thin">
            {state.recentRounds.slice(0, 8).length ? (
              state.recentRounds.slice(0, 8).map((round) => (
                <button
                  key={round.id}
                  className={cn(
                    "h-7 shrink-0 rounded-full px-2.5 text-[11px] font-black",
                    round.status === "WON" ? "bg-felt/[0.12] text-felt" : "bg-ember/[0.12] text-ember"
                  )}
                  onClick={() => {
                    setLastRound(round);
                    setDisplayMultiplier(Number(round.result));
                  }}
                >
                  {Number(round.result).toFixed(2)}x
                </button>
              ))
            ) : (
              <span className="h-7 rounded-full bg-white/[0.04] px-2.5 pt-1.5 text-[11px] font-bold text-slate-500">Aucun round</span>
            )}
          </div>

          <div className="relative mx-auto grid min-h-[296px] max-w-[820px] place-items-center rounded-lg border border-white/10 bg-black/35 px-3 py-7">
            <div className="absolute inset-0 overflow-hidden rounded-lg">
              <div className="absolute inset-x-6 top-1/2 h-px bg-gradient-to-r from-transparent via-white/10 to-transparent" />
              <div className={cn("absolute left-1/2 top-1/2 h-[180px] w-[180px] -translate-x-1/2 -translate-y-1/2 rounded-full blur-3xl transition", lastRound?.status === "WON" ? "bg-felt/15" : "bg-ember/10")} />
            </div>
            <div
              className={cn(
                "relative grid min-h-[118px] min-w-[230px] place-items-center rounded-lg border bg-black px-8 shadow-panel transition",
                rolling ? "border-felt/40" : lastRound?.status === "WON" ? "border-felt/50" : lastRound ? "border-ember/45" : "border-white/10"
              )}
            >
              <span className={cn("text-[48px] font-black leading-none text-white transition sm:text-[64px]", rolling && "scale-[1.03]")}>{displayMultiplier.toFixed(2)}x</span>
            </div>
          </div>

          <div className="mt-4 grid grid-cols-2 gap-2">
            <label className="rounded-lg bg-white/[0.055] p-2.5">
              <span className="block text-[11px] font-bold text-slate-300">Multiplicateur</span>
              <span className="mt-1 flex items-center justify-between gap-2 text-sm font-semibold text-white">
                <input
                  value={targetMultiplier}
                  onChange={(event) => setTargetMultiplier(event.target.value)}
                  inputMode="decimal"
                  className="min-w-0 flex-1 border-0 bg-transparent p-0 text-sm font-semibold text-white focus:ring-0"
                />
                <span className="text-slate-300">x</span>
              </span>
            </label>
            <NumberTile label="Chance" value={chance.toFixed(8)} suffix="%" />
          </div>
        </div>

        <div className="border-b border-white/10 p-3 sm:p-4">
          <button
            onClick={mode === "manual" ? placeRound : startAuto}
            disabled={rolling}
            className="grid h-11 w-full place-items-center rounded-lg bg-gradient-to-r from-felt to-emerald-300 text-sm font-black text-ink-950 shadow-[0_16px_36px_rgba(15,191,143,.22)] transition active:scale-[.99] disabled:opacity-60"
          >
            {rolling ? <Loader2 className="h-4 w-4 animate-spin" /> : mode === "manual" ? "Pari" : "Démarrer le pari automatique"}
          </button>
          <StakeLimitNote min={state.config.minStake} max={state.config.maxStake} currency={state.currency} />

          {mode !== "manual" ? (
            <button onClick={stopAuto} className="mt-2 h-9 w-full rounded-lg border border-white/10 bg-white/[0.035] text-xs font-bold text-slate-200">
              Stop
            </button>
          ) : null}

          {message ? <p className="mt-2 rounded-lg border border-white/10 bg-white/[0.035] px-3 py-2 text-xs font-bold text-slate-300">{message}</p> : null}

          <div className="mt-3 space-y-3">
            <StakeInput
              currency={state.currency}
              stake={stake}
              potentialProfit={potentialProfit}
              onStake={setStake}
              onHalf={halveStake}
              onDouble={doubleStake}
            />

            {mode === "auto" ? <AutoPanel betCount={betCount} setBetCount={setBetCount} /> : null}

            <div className="grid grid-cols-2 gap-1.5 rounded-lg bg-white/[0.055] p-1.5">
              {modes.map((item) => (
                <button
                  key={item.value}
                  onClick={() => setMode(item.value)}
                  className={cn("h-9 rounded-md text-xs font-black transition", mode === item.value ? "bg-[#373d4b] text-white" : "text-slate-400 hover:text-white")}
                >
                  {item.label}
                </button>
              ))}
            </div>
          </div>
        </div>

        <div className="relative flex h-12 items-center justify-between px-3 sm:px-4">
          <div className="flex items-center gap-2">
            <IconButton active={settingsOpen} label="Paramètres" onClick={() => setSettingsOpen((value) => !value)} icon={<Settings className="h-4 w-4" />} />
            <IconButton active={statsOpen} label="Stats" onClick={() => setStatsOpen(true)} icon={<BarChart3 className="h-4 w-4" />} />
            <IconButton label="Favori" onClick={() => setMessage("Limbo ajouté à tes favoris.")} icon={<Star className="h-4 w-4" />} />
          </div>
          <button onClick={() => setFairnessOpen((value) => !value)} className="flex items-center gap-1.5 text-xs font-black text-slate-400 underline decoration-slate-600 underline-offset-4">
            Équité
            <Check className="h-3.5 w-3.5 text-felt" />
          </button>

          {settingsOpen ? (
            <SettingsPopover
              turbo={turbo}
              maxBet={maxBet}
              silent={silent}
              onTurbo={setTurbo}
              onMaxBet={(value) => {
                setMaxBet(value);
                if (value) setStake(state.config.maxStake);
              }}
              onSilent={setSilent}
            />
          ) : null}
        </div>
      </section>

      {fairnessOpen ? (
        <LimboFairnessPanel
          state={state}
          revealedSeed={revealedSeed}
          clientSeedInput={clientSeedInput}
          verifyInput={verifyInput}
          verifyResult={verifyResult}
          setClientSeedInput={setClientSeedInput}
          setVerifyInput={setVerifyInput}
          onRotate={rotateSeeds}
          onVerify={verifySeed}
          onClose={() => setFairnessOpen(false)}
        />
      ) : null}

      <GameDetailsPanel kind="limbo" rounds={state.recentRounds} currency={state.currency} />

      <section className="space-y-2.5">
        <div className="flex items-center gap-2">
          <span className="grid h-7 w-7 place-items-center rounded-lg bg-felt text-ink-950">
            <Sparkles className="h-4 w-4" />
          </span>
          <h2 className="text-lg font-black text-white">Plus de ZiraBet Games</h2>
        </div>
        <div className="-mx-1 flex gap-2 overflow-x-auto px-1 pb-1 scrollbar-thin">
          {otherGames.slice(0, 5).map((game) => (
            <Link key={game.slug} href={`/casino/games/${game.slug}`} className="relative aspect-[150/205] w-[112px] shrink-0 overflow-hidden rounded-lg border border-white/10 bg-[#151a22] sm:w-[138px]">
              <Image src={game.image} alt="" fill sizes="140px" className="object-cover" />
              <div className="absolute inset-0 bg-gradient-to-t from-black/82 via-transparent to-transparent" />
              <div className="absolute inset-x-0 bottom-0 p-2">
                <p className="text-sm font-black uppercase leading-none text-white">{game.title}</p>
              </div>
            </Link>
          ))}
        </div>
      </section>

      {statsOpen ? <StatsModal state={state} onClose={() => setStatsOpen(false)} /> : null}
    </div>
  );
}

function NumberTile({ label, value, suffix }: { label: string; value: string; suffix: string }) {
  return (
    <div className="rounded-lg bg-white/[0.055] p-2.5">
      <span className="block text-[11px] font-bold text-slate-300">{label}</span>
      <span className="mt-1 flex items-center justify-between text-sm font-semibold text-white">
        {value}
        <span className="text-slate-300">{suffix}</span>
      </span>
    </div>
  );
}

function StakeInput({
  currency,
  stake,
  potentialProfit,
  onStake,
  onHalf,
  onDouble
}: {
  currency: string;
  stake: string;
  potentialProfit: number;
  onStake: (value: string) => void;
  onHalf: () => void;
  onDouble: () => void;
}) {
  return (
    <>
      <CasinoStakeInput value={stake} currency={currency} onChange={onStake} onHalf={onHalf} onDouble={onDouble} />

      <div>
        <div className="mb-1.5 flex items-center justify-between text-[12px] font-bold text-slate-200">
          <span>Profit</span>
          <span className="text-slate-500">{formatAmountInputFixed(potentialProfit)} {currency}</span>
        </div>
        <div className="flex h-10 items-center gap-2 rounded-lg border border-white/10 bg-black/20 px-3 text-sm font-semibold text-white">
          <span className="grid h-5 w-5 place-items-center rounded-full bg-felt text-[12px] font-black text-ink-950">€</span>
          {formatInputAmount(Math.max(0, potentialProfit))}
        </div>
      </div>
    </>
  );
}

function AutoPanel({ betCount, setBetCount }: { betCount: string; setBetCount: (value: string) => void }) {
  return (
    <div className="space-y-3">
      <div>
        <div className="mb-1.5 text-[12px] font-bold text-slate-200">Nombre de paris</div>
        <div className="flex h-10 overflow-hidden rounded-lg bg-[#202631]">
          <input
            value={betCount}
            onChange={(event) => setBetCount(event.target.value)}
            inputMode="numeric"
            className="min-w-0 flex-1 border-0 bg-transparent px-3 text-sm font-semibold text-white placeholder:text-slate-500 focus:ring-0"
            placeholder="0"
          />
          <button onClick={() => setBetCount("0")} className="grid w-14 place-items-center border-l border-white/10 text-white">
            <Infinity className="h-4 w-4" />
          </button>
        </div>
      </div>
      <div className="grid grid-cols-2 gap-2 rounded-lg border border-white/10 bg-black/20 p-3 text-xs text-slate-400">
        <span>Sur victoire</span>
        <span>En cas de perte</span>
        <span className="font-bold text-white">-</span>
        <span className="font-bold text-white">-</span>
        <span>Arrêt sur profit</span>
        <span>Arrêt en cas de perte</span>
        <span className="font-bold text-white">0.00</span>
        <span className="font-bold text-white">0.00</span>
      </div>
    </div>
  );
}

function SettingsPopover({
  turbo,
  maxBet,
  silent,
  onTurbo,
  onMaxBet,
  onSilent
}: {
  turbo: boolean;
  maxBet: boolean;
  silent: boolean;
  onTurbo: (value: boolean) => void;
  onMaxBet: (value: boolean) => void;
  onSilent: (value: boolean) => void;
}) {
  return (
    <div className="absolute bottom-11 left-3 z-20 w-[210px] overflow-hidden rounded-lg border border-white/10 bg-[#202631] shadow-panel">
      <ToggleRow icon={<Gauge className="h-4 w-4" />} label="Mode Turbo" checked={turbo} onChange={onTurbo} />
      <ToggleRow icon={<Rocket className="h-4 w-4" />} label="Pari maximum" checked={maxBet} onChange={onMaxBet} />
      <ToggleRow icon={<X className="h-4 w-4" />} label="Silencieux" checked={silent} onChange={onSilent} />
    </div>
  );
}

function ToggleRow({ icon, label, checked, onChange }: { icon: ReactNode; label: string; checked: boolean; onChange: (value: boolean) => void }) {
  return (
    <button onClick={() => onChange(!checked)} className="flex h-12 w-full items-center justify-between border-b border-white/10 px-3 text-xs font-bold text-white last:border-b-0">
      <span className="flex items-center gap-2">
        {icon}
        {label}
      </span>
      <span className={cn("relative h-6 w-11 rounded-full transition", checked ? "bg-felt" : "bg-black")}>
        <span className={cn("absolute top-1 h-4 w-4 rounded-full bg-white transition", checked ? "left-6" : "left-1")} />
      </span>
    </button>
  );
}

function LimboFairnessPanel({
  state,
  revealedSeed,
  clientSeedInput,
  verifyInput,
  verifyResult,
  setClientSeedInput,
  setVerifyInput,
  onRotate,
  onVerify,
  onClose
}: {
  state: LimboState;
  revealedSeed: null | { serverSeed: string; clientSeed: string; nonce: number; serverSeedHash: string };
  clientSeedInput: string;
  verifyInput: { serverSeed: string; clientSeed: string; nonce: string };
  verifyResult: null | { serverSeedHash: string; result: string };
  setClientSeedInput: (value: string) => void;
  setVerifyInput: (value: { serverSeed: string; clientSeed: string; nonce: string }) => void;
  onRotate: () => void;
  onVerify: () => void;
  onClose: () => void;
}) {
  const [tab, setTab] = useState<"seeds" | "verify">("seeds");

  return (
    <section
      className="fixed inset-x-0 top-0 bottom-[calc(4.65rem+env(safe-area-inset-bottom))] z-[49] flex flex-col overflow-hidden border-b border-white/10 bg-[#0d1017] text-white shadow-panel"
      aria-label="Équité Limbo"
    >
      <header className="flex h-[72px] shrink-0 items-center justify-between border-b border-white/10 px-4">
        <div className="flex min-w-0 items-center gap-2">
          <h2 className="truncate text-[22px] font-extrabold text-white">Équité</h2>
          <span className="rounded-md bg-felt px-2 py-1 text-[11px] font-black text-ink-950">Limbo</span>
          <ChevronDown className="h-4 w-4 text-slate-300" />
        </div>
        <button onClick={onClose} className="grid h-9 w-9 place-items-center rounded-full text-slate-300 hover:bg-white/[0.07] hover:text-white" aria-label="Fermer l'équité">
          <X className="h-5 w-5" />
        </button>
      </header>

      <div className="min-h-0 flex-1 overflow-y-auto px-4 py-4 scrollbar-thin">
        <div className="mx-auto h-1 w-9 rounded-full bg-slate-600" />
        <div className="mx-auto w-full max-w-[720px]">
          <div className="mt-4 grid grid-cols-2 border-b border-white/10 text-sm font-black">
            <button onClick={() => setTab("seeds")} className={cn("h-10 border-b-2", tab === "seeds" ? "border-felt text-felt" : "border-transparent text-white")}>Seeds</button>
            <button onClick={() => setTab("verify")} className={cn("h-10 border-b-2", tab === "verify" ? "border-felt text-felt" : "border-transparent text-white")}>Vérifier</button>
          </div>

          {tab === "seeds" ? (
            <div className="mt-4 space-y-3">
              <ReadOnlyField label="Seed de client actif" value={state.seedPair.clientSeed} />
              <ReadOnlyField label="Seed de serveur actif (haché)" value={state.seedPair.serverSeedHash} />
              <ReadOnlyField label="Total des paris effectués avec la paire" value={String(state.seedPair.nonce)} />
              <h3 className="pt-2 text-lg font-black text-white">Faire pivoter la paire de seed</h3>
              <label className="block">
                <span className="text-xs font-bold text-slate-200">Nouvelle seed de client</span>
                <div className="mt-1.5 flex gap-2">
                  <input
                    value={clientSeedInput}
                    onChange={(event) => setClientSeedInput(event.target.value)}
                    className="h-10 min-w-0 flex-1 rounded-lg border-0 bg-white/[0.055] px-3 text-sm font-semibold text-white placeholder:text-slate-500 focus:ring-1 focus:ring-felt"
                  />
                  <button onClick={onRotate} className="h-10 rounded-lg bg-felt px-4 text-xs font-black text-ink-950">Changer</button>
                </div>
              </label>
              {revealedSeed ? (
                <div className="rounded-lg border border-felt/20 bg-felt/[0.08] p-3">
                  <div className="text-xs font-black text-felt">Seed précédente révélée</div>
                  <div className="mt-2 space-y-2">
                    <ReadOnlyField label="Server seed" value={revealedSeed.serverSeed} compact />
                    <ReadOnlyField label="Client seed" value={revealedSeed.clientSeed} compact />
                  </div>
                </div>
              ) : null}
            </div>
          ) : (
            <div className="mt-4 space-y-3">
              <VerifyInput label="Jeu" value="Limbo" readOnly />
              <VerifyInput label="Seed de client" value={verifyInput.clientSeed} onChange={(clientSeed) => setVerifyInput({ ...verifyInput, clientSeed })} />
              <VerifyInput label="Seed de serveur" value={verifyInput.serverSeed} onChange={(serverSeed) => setVerifyInput({ ...verifyInput, serverSeed })} />
              <VerifyInput label="Nonce" value={verifyInput.nonce} onChange={(nonce) => setVerifyInput({ ...verifyInput, nonce })} />
              <button onClick={onVerify} className="h-10 w-full rounded-lg bg-felt text-xs font-black text-ink-950">Vérifier le round</button>
              {verifyResult ? (
                <div className="rounded-lg border border-white/10 bg-black/20 p-3 text-xs text-slate-300">
                  <div>Résultat : <span className="font-black text-felt">{verifyResult.result}x</span></div>
                  <div className="mt-1 truncate">Hash : {verifyResult.serverSeedHash}</div>
                </div>
              ) : null}
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

function ReadOnlyField({ label, value, compact = false }: { label: string; value: string; compact?: boolean }) {
  return (
    <label className="block">
      <span className="text-xs font-bold text-slate-200">{label}</span>
      <div className={cn("mt-1.5 flex items-center gap-2 rounded-lg border border-white/10 bg-black/20 px-3", compact ? "h-9" : "h-11")}>
        <span className="min-w-0 flex-1 truncate text-sm font-semibold text-slate-400">{value}</span>
        <button onClick={() => void navigator.clipboard?.writeText(value)} className="text-slate-200" aria-label="Copier">
          <Copy className="h-4 w-4" />
        </button>
      </div>
    </label>
  );
}

function VerifyInput({ label, value, onChange, readOnly }: { label: string; value: string; onChange?: (value: string) => void; readOnly?: boolean }) {
  return (
    <label className="block">
      <span className="text-xs font-bold text-slate-200">{label}</span>
      <input
        value={value}
        onChange={(event) => onChange?.(event.target.value)}
        readOnly={readOnly}
        className="mt-1.5 h-10 w-full rounded-lg border-0 bg-white/[0.055] px-3 text-sm font-semibold text-white placeholder:text-slate-500 focus:ring-1 focus:ring-felt"
      />
    </label>
  );
}

function StatsModal({ state, onClose }: { state: LimboState; onClose: () => void }) {
  return (
    <div className="fixed inset-0 z-[95] flex items-start justify-center overflow-y-auto bg-black/70 px-4 py-12 backdrop-blur" onClick={onClose}>
      <div className="w-full max-w-[330px] rounded-lg border border-white/10 bg-[#151a22] p-3 shadow-panel" onClick={(event) => event.stopPropagation()}>
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2 text-sm font-black text-white">
            <BarChart3 className="h-4 w-4" />
            Live Stats
          </div>
          <button onClick={onClose} className="text-slate-300">
            <X className="h-5 w-5" />
          </button>
        </div>
        <div className="mt-3 rounded-lg bg-white/[0.055] p-3">
          <div className="grid grid-cols-2 gap-3 text-sm">
            <Stat label="Profit" value={formatMoney(state.stats.profit, state.currency)} positive={Number(state.stats.profit) >= 0} />
            <Stat label="Gains" value={String(state.stats.wins)} positive />
            <Stat label="Misé" value={formatMoney(state.stats.stake, state.currency)} />
            <Stat label="Pertes" value={String(state.stats.losses)} negative />
          </div>
        </div>
        <div className="mt-3 space-y-1.5">
          {state.recentRounds.slice(0, 6).map((round) => (
            <div key={round.id} className="flex h-9 items-center justify-between rounded-lg bg-black/20 px-2.5 text-xs font-bold">
              <span className={round.status === "WON" ? "text-felt" : "text-ember"}>{Number(round.result).toFixed(2)}x</span>
              <span className="text-slate-400">{Number(round.multiplier).toFixed(2)}x</span>
              <span className="text-white">{formatMoney(round.profit, round.currency)}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function Stat({ label, value, positive, negative }: { label: string; value: string; positive?: boolean; negative?: boolean }) {
  return (
    <div>
      <div className="text-xs font-bold text-slate-500">{label}</div>
      <div className={cn("mt-1 text-sm font-black", positive ? "text-felt" : negative ? "text-ember" : "text-white")}>{value}</div>
    </div>
  );
}

function IconButton({ icon, label, active, onClick }: { icon: ReactNode; label: string; active?: boolean; onClick: () => void }) {
  return (
    <button onClick={onClick} className={cn("grid h-8 w-8 place-items-center rounded-lg text-slate-200 transition hover:bg-white/[0.06]", active && "text-felt")} aria-label={label}>
      {icon}
    </button>
  );
}

const modes: Array<{ value: Mode; label: string }> = [
  { value: "manual", label: "Manuel" },
  { value: "auto", label: "Auto" }
];

function round8(value: number) {
  return Number(value.toFixed(8));
}

function wait(ms: number) {
  return new Promise((resolve) => window.setTimeout(resolve, ms));
}

function formatInputAmount(value: number) {
  return formatAmountInput(value);
}

function formatMoney(value: string | number, currency: string) {
  return new Intl.NumberFormat("fr-FR", { style: "currency", currency }).format(Number(value));
}
