"use client";

import Image from "next/image";
import { ChevronDown, Medal, Sparkles, Trophy } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { getMiniGame } from "@/lib/casino-games";
import { cn } from "@/lib/utils";

export type CasinoGameRoundSummary = {
  id: string;
  currency: string;
  stake: string;
  payout: string;
  profit: string;
  multiplier: string;
  chance: string;
  result: string;
  status: "ACTIVE" | "WON" | "LOST" | "VOID";
  createdAt: string;
  playerName?: string;
};

type GameDetailsKind = "dice" | "limbo" | "mines" | "blackjack" | "plinko";
type Tab = "best" | "lucky" | "description";
type CasinoLeaderboard = {
  best: CasinoGameRoundSummary[];
  lucky: CasinoGameRoundSummary[];
};

export function GameDetailsPanel({
  kind,
  rounds,
  currency
}: {
  kind: GameDetailsKind;
  rounds: CasinoGameRoundSummary[];
  currency: string;
}) {
  const [open, setOpen] = useState(true);
  const [tab, setTab] = useState<Tab>("best");
  const [leaderboard, setLeaderboard] = useState<CasinoLeaderboard | null>(null);
  const game = getMiniGame(kind);
  const wonRounds = useMemo(() => rounds.filter((round) => round.status === "WON" && Number(round.payout) > 0), [rounds]);
  const bestRounds = useMemo(() => [...wonRounds].sort((a, b) => Number(b.payout) - Number(a.payout)).slice(0, 3), [wonRounds]);
  const luckyRounds = useMemo(() => [...wonRounds].sort((a, b) => Number(b.multiplier) - Number(a.multiplier)).slice(0, 3), [wonRounds]);
  const bestLeaderboard = (leaderboard ? leaderboard.best : bestRounds).slice(0, 3);
  const luckyLeaderboard = (leaderboard ? leaderboard.lucky : luckyRounds).slice(0, 3);

  useEffect(() => {
    let cancelled = false;

    async function loadLeaderboard() {
      try {
        const response = await fetch(`/api/casino/leaderboard?game=${kind}`, { cache: "no-store" });
        const payload = (await response.json()) as { ok: boolean; data?: CasinoLeaderboard };

        if (!cancelled && response.ok && payload.ok && payload.data) {
          setLeaderboard(payload.data);
        }
      } catch {
        if (!cancelled) setLeaderboard(null);
      }
    }

    void loadLeaderboard();
    return () => {
      cancelled = true;
    };
  }, [kind, rounds.length]);

  return (
    <section className="overflow-hidden rounded-lg border border-white/10 bg-[#111720] shadow-panel">
      <button className="flex h-14 w-full items-center justify-between px-3 text-left" onClick={() => setOpen((value) => !value)}>
        <div className="flex items-center gap-2">
          <h2 className="text-[22px] font-black leading-none text-white">{game?.title ?? kind}</h2>
          <span className="rounded-lg bg-white/[0.08] px-2 py-1 text-xs font-black text-slate-200">ZiraBet Games</span>
        </div>
        <ChevronDown className={cn("h-5 w-5 text-slate-300 transition", open && "rotate-180")} />
      </button>

      {open ? (
        <div className="border-t border-white/10 bg-black/22 p-3">
          <div className="grid grid-cols-3 gap-1.5 rounded-lg bg-white/[0.055] p-1.5">
            {tabs.map((item) => (
              <button
                key={item.value}
                onClick={() => setTab(item.value)}
                className={cn(
                  "h-9 rounded-md text-[12px] font-black transition",
                  tab === item.value ? "bg-[#373d4b] text-white" : "text-slate-400 hover:text-white"
                )}
              >
                {item.label}
              </button>
            ))}
          </div>

          {tab === "description" ? (
            <DescriptionContent kind={kind} currency={currency} />
          ) : (
            <Leaderboard
              rows={tab === "best" ? bestLeaderboard : luckyLeaderboard}
              kind={kind}
              mode={tab}
              currency={currency}
            />
          )}
        </div>
      ) : null}
    </section>
  );
}

function Leaderboard({
  rows,
  kind,
  mode,
  currency
}: {
  rows: CasinoGameRoundSummary[];
  kind: GameDetailsKind;
  mode: Exclude<Tab, "description">;
  currency: string;
}) {
  return (
    <div className="mt-3 rounded-lg border border-white/10 bg-black/20 p-3">
      <div className="flex h-10 items-center justify-between border-b border-white/10 text-[11px] font-black uppercase tracking-[0.06em] text-slate-500">
        <span>Rang</span>
        <span>{mode === "best" ? "Paiement" : kind === "dice" ? "Roll" : "Multiplicateur"}</span>
      </div>

      {rows.length ? (
        <div className="mt-2 space-y-1.5">
          {rows.map((round, index) => (
            <div key={round.id} className={cn("grid grid-cols-[66px_1fr_auto] items-center gap-2 rounded-lg px-2.5 py-2 text-xs font-bold", index === 1 ? "bg-white/[0.045]" : "bg-transparent")}>
              <span className="flex items-center gap-1.5 text-white">
                <RankIcon rank={index + 1} />
                {index + 1}{index === 0 ? "er" : "ème"}
              </span>
              <span className="truncate text-slate-400">{round.playerName ?? "Joueur"}</span>
              <span className="font-black text-felt">
                {mode === "best" ? formatMoney(round.payout, round.currency || currency) : `${Number(kind === "dice" ? round.result : round.multiplier).toLocaleString("fr-FR", { maximumFractionDigits: 2 })}x`}
              </span>
            </div>
          ))}
        </div>
      ) : (
        <div className="grid min-h-[116px] place-items-center text-center">
          <div>
            <Sparkles className="mx-auto h-5 w-5 text-slate-600" />
            <p className="mt-2 text-xs font-bold text-slate-500">Aucun gain enregistré pour le moment.</p>
          </div>
        </div>
      )}
    </div>
  );
}

function DescriptionContent({ kind, currency }: { kind: GameDetailsKind; currency: string }) {
  const game = getMiniGame(kind);
  const copy = kind === "limbo" ? limboCopy : kind === "mines" ? minesCopy : kind === "blackjack" ? blackjackCopy : kind === "plinko" ? plinkoCopy : diceCopy;
  const advantage = kind === "blackjack" ? "0,52 %" : "1,00 %";

  return (
    <div className="mt-3 space-y-4">
      <div className="flex flex-col items-center border-b border-white/10 pb-4 text-center">
        {game ? (
          <div className="relative aspect-[150/205] w-[116px] overflow-hidden rounded-lg border border-white/10 bg-[#151a22]">
            <Image src={game.image} alt="" fill sizes="116px" className="object-cover" />
          </div>
        ) : null}
        <div className="mt-3 text-xs font-bold text-slate-400">
          Publié : juillet 2026 <span className="text-slate-600">|</span> Avantage : {advantage}
        </div>
        <div className="mt-2 flex gap-2">
          <span className="rounded-md bg-white/[0.08] px-2 py-1 text-[11px] font-black text-slate-200">ZiraBet Games</span>
          <span className="rounded-md border border-white/60 px-2 py-1 text-[11px] font-black text-white">Originaux</span>
        </div>
      </div>

      <div className="space-y-3 text-xs leading-5 text-slate-400">
        <p>{copy.intro}</p>
        <h3 className="text-[15px] font-black text-white">Comment fonctionne {copy.name} ?</h3>
        {copy.steps.map((step) => (
          <p key={step.title}>
            <span className="font-black text-slate-200">{step.title}</span>
            <br />
            {step.body}
          </p>
        ))}
        <h3 className="text-[15px] font-black text-white">Faits clés</h3>
        <div className="overflow-hidden rounded-lg border border-white/10">
          {copy.facts.map((fact, index) => (
            <div key={fact.label} className={cn("grid grid-cols-[42%_58%] text-xs", index % 2 === 0 ? "bg-white/[0.045]" : "bg-transparent")}>
              <div className="px-3 py-2 font-black text-slate-200">{fact.label}</div>
              <div className="truncate px-3 py-2 text-slate-400">{fact.value}</div>
            </div>
          ))}
        </div>
        <p>
          Les résultats sont générés côté serveur, avec seed de serveur, seed de client et nonce. Chaque round peut être vérifié dans l’onglet Équité après rotation de seed.
        </p>
        <p className="rounded-lg border border-white/10 bg-white/[0.035] p-3 text-[11px] leading-5 text-slate-400">
          Devise active : <span className="font-black text-white">{currency}</span>. Les mises utilisent le solde réel en premier, puis le solde bonus disponible si nécessaire.
        </p>
      </div>
    </div>
  );
}

function RankIcon({ rank }: { rank: number }) {
  if (rank === 1) return <Trophy className="h-4 w-4 text-gold" />;
  if (rank === 2) return <Medal className="h-4 w-4 text-slate-400" />;
  return <Medal className="h-4 w-4 text-amber-700" />;
}

const tabs: Array<{ value: Tab; label: string }> = [
  { value: "best", label: "Meilleurs gains" },
  { value: "lucky", label: "Gains chanceux" },
  { value: "description", label: "Description" }
];

const limboCopy = {
  name: "Limbo",
  intro:
    "Limbo est un jeu de multiplicateur rapide : choisis la cible que tu veux atteindre, place ta mise, puis laisse le résultat tomber. Plus la cible est élevée, plus la chance baisse.",
  steps: [
    { title: "1. Définis ta mise", body: "Entre le montant à risquer pour le prochain round. Le wallet se met à jour juste après le règlement." },
    { title: "2. Choisis ton multiplicateur", body: "Un multiplicateur faible touche plus souvent. Un multiplicateur élevé est plus rare, mais le paiement potentiel augmente." },
    { title: "3. Lance le pari", body: "Le round est résolu côté serveur et le résultat s’affiche avec une animation courte." },
    { title: "4. Vérifie le résultat", body: "Si le résultat est supérieur ou égal à ta cible, le gain est crédité automatiquement." }
  ],
  facts: [
    { label: "Type", value: "Multiplicateur" },
    { label: "Round", value: "Instantané" },
    { label: "Contrôles", value: "Manuel et Auto" },
    { label: "Fair-play", value: "Seed vérifiable" }
  ]
};

const diceCopy = {
  name: "Dice",
  intro:
    "Dice est un jeu de probabilité lisible : choisis une chance, un seuil au-dessus ou en-dessous, puis lance le roll. Le multiplicateur est calculé automatiquement.",
  steps: [
    { title: "1. Choisis la chance", body: "Plus la chance est basse, plus le multiplicateur potentiel monte. Le seuil s’ajuste en direct." },
    { title: "2. Place ta mise", body: "Entre le montant du round et visualise le profit potentiel avant de jouer." },
    { title: "3. Lance le roll", body: "Le résultat apparaît sur la barre avec une animation rapide." },
    { title: "4. Contrôle l’équité", body: "La seed active et le nonce permettent de vérifier les résultats passés." }
  ],
  facts: [
    { label: "Type", value: "Roll 0-100" },
    { label: "Round", value: "Instantané" },
    { label: "Contrôles", value: "Manuel, Auto, Avancé" },
    { label: "Fair-play", value: "Seed vérifiable" }
  ]
};

const minesCopy = {
  name: "Mines",
  intro:
    "Mines est une grille 5x5 rapide et nerveuse : choisis ta mise, le nombre de mines, puis révèle les cases sûres pour faire monter ton multiplicateur avant d'encaisser.",
  steps: [
    { title: "1. Définis ta mise", body: "Entre le montant à risquer pour la partie. Une partie active doit être terminée ou encaissée avant d'en lancer une nouvelle." },
    { title: "2. Choisis les mines", body: "Moins il y a de mines, plus le rythme est stable. Plus il y en a, plus chaque case sûre augmente le paiement potentiel." },
    { title: "3. Révèle les cases", body: "Chaque case sûre ajoute une animation de gemme et augmente le multiplicateur. Une mine met fin à la partie." },
    { title: "4. Encaisse à temps", body: "Dès qu'au moins une case sûre est révélée, tu peux encaisser pour créditer le gain sur ton wallet." }
  ],
  facts: [
    { label: "Type", value: "Grille 5x5" },
    { label: "Round", value: "Progressif" },
    { label: "Contrôles", value: "Manuel et Auto" },
    { label: "Fair-play", value: "Seed vérifiable" }
  ]
};

const blackjackCopy = {
  name: "Blackjack",
  intro:
    "Blackjack reprend les sensations d'une vraie table avec une distribution animée, des décisions rapides et un règlement automatique. L'objectif reste simple : battre le croupier sans dépasser 21.",
  steps: [
    { title: "1. Place ta mise", body: "Entre le montant de la main. Le solde réel est utilisé en premier, puis le solde bonus si nécessaire." },
    { title: "2. Reçois les cartes", body: "La main du joueur et celle du croupier sont distribuées avec une seed vérifiable. La carte cachée du croupier reste masquée jusqu'au règlement." },
    { title: "3. Choisis ton action", body: "Pioche, reste, double ou splitte si la main le permet. Chaque action met à jour la main sans recharger la page." },
    { title: "4. Règlement instantané", body: "Le croupier tire jusqu'a 17. Les gains, égalités et pertes sont crédités ou soldés automatiquement sur le wallet." }
  ],
  facts: [
    { label: "Type", value: "Cartes" },
    { label: "Blackjack", value: "Paiement 3:2" },
    { label: "Contrôles", value: "Hit, Stand, Double, Split" },
    { label: "Fair-play", value: "Deck vérifiable" }
  ]
};

const plinkoCopy = {
  name: "Plinko",
  intro:
    "Plinko fait tomber une bille dans un plateau de paliers. Chaque rebond détermine le chemin jusqu'à une case finale, et le paiement correspond exactement au multiplicateur de cette case.",
  steps: [
    { title: "1. Définis ta mise", body: "Entre le montant à risquer pour le prochain tirage. La limite minimale et maximale reste visible sous le bouton de jeu." },
    { title: "2. Choisis les lignes et le risque", body: "Plus il y a de lignes, plus la trajectoire est longue. Un risque élevé concentre les gros multiplicateurs sur les bords." },
    { title: "3. Lance la bille", body: "La bille descend visuellement dans le plateau. Son chemin varie à chaque nonce et reste vérifiable après rotation de seed." },
    { title: "4. Vérifie la case finale", body: "Le gain affiché correspond à la case d'arrivée. La table des multiplicateurs est affichée directement sous les pins." }
  ],
  facts: [
    { label: "Type", value: "Bille et paliers" },
    { label: "Round", value: "Animation progressive" },
    { label: "Contrôles", value: "Lignes, risque, Auto" },
    { label: "Fair-play", value: "Seed vérifiable" }
  ]
};

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