import { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { Check, Undo2, Award, Trash2, BookOpen } from "lucide-react";
import * as Icons from "lucide-react";
import { useLiveQuery } from "dexie-react-hooks";
import { db } from "../database/db";
import { useGameStore } from "../stores/gameStore";
import { useGameConfig } from "../games";
import { useGameTheme } from "../hooks/useGameTheme";
import { RoundScore } from "../types";
import { Button } from "../components/ui/button";
import { Card, CardContent } from "../components/ui/card";
import { Input } from "../components/ui/input";
import { PlanetMark } from "../components/Logo";
import { motion } from "framer-motion";
import { calculatePlayerTotalScore } from "../utils/scoring";

export default function PlayGame() {
  const { sessionId } = useParams<{ sessionId: string }>();
  const navigate = useNavigate();
  const { activeSession, loadSession, addRound, undoLastRound, finishGame } =
    useGameStore();
  const [currentScores, setCurrentScores] = useState<Record<string, string>>(
    {},
  );
  const [caboCalls, setCaboCalls] = useState<
    Record<string, "success" | "fail" | null>
  >({});
  const [kamikazePlayer, setKamikazePlayer] = useState<string | null>(null);
  const [detailedScores, setDetailedScores] = useState<
    Record<string, Record<string, string>>
  >({});

  const [currentCategoryIndex, setCurrentCategoryIndex] = useState(0);

  // Keep active session players updated if a global player rename happens
  const playersInDb = useLiveQuery(() => db.players.toArray());

  const gameConfig = useGameConfig(activeSession?.gameId);
  useGameTheme(gameConfig);

  // Effective scoring categories (may depend on the session's options).
  const categories =
    gameConfig?.getScoringCategories?.(activeSession?.options ?? {}) ??
    gameConfig?.scoringCategories;

  useEffect(() => {
    if (sessionId) {
      loadSession(sessionId);
    }
  }, [sessionId, loadSession]);

  useEffect(() => {
    if (!activeSession || !gameConfig) return;

    // Check end conditions after a round is added
    let shouldEnd = false;

    // Fixed rounds check
    if (
      gameConfig.fixedRounds &&
      activeSession.rounds.length >= gameConfig.fixedRounds
    ) {
      shouldEnd = true;
    }

    // Target score check
    const currentTargetScore = gameConfig.getTargetScore
      ? gameConfig.getTargetScore(activeSession.options)
      : gameConfig.targetScore;

    if (currentTargetScore !== undefined) {
      const isTargetReached = activeSession.players.some((p) => {
        // Calculate total to check if it triggers end game conditions
        const total = calculateTotalScore(p.id);

        if (gameConfig.targetScoreCondition === "exceeds") {
          return total > currentTargetScore;
        }
        return total >= currentTargetScore;
      });
      if (isTargetReached) {
        shouldEnd = true;
      }
    }

    if (shouldEnd && activeSession.status === "playing") {
      handleEndGame();
    }
  }, [activeSession?.rounds.length]);

  if (!activeSession)
    return <div className="p-4 text-center mt-10">Chargement...</div>;

  if (!gameConfig)
    return <div className="p-4 text-center">Jeu introuvable</div>;

  const Icon = gameConfig.icon ? (Icons as any)[gameConfig.icon] : null;

  // Use the most up to date names if available
  const displayPlayers = activeSession.players.map((p) => {
    const dbPlayer = playersInDb?.find((dbp) => dbp.id === p.id);
    return dbPlayer ? { ...p, name: dbPlayer.name } : p;
  });

  const calculateTotalScore = (playerId: string) => {
    return calculatePlayerTotalScore(
      playerId,
      activeSession.rounds,
      gameConfig,
      true,
    );
  };

  const getLiveTotalScore = (playerId: string) => {
    let total = calculateTotalScore(playerId);
    if (categories) {
      const pDetails = detailedScores[playerId] || {};
      for (const key in pDetails) {
        const val = parseInt(pDetails[key] || "0", 10);
        if (!isNaN(val)) total += val;
      }
    } else {
      const val = parseInt(currentScores[playerId] || "0", 10);
      if (!isNaN(val)) total += val;
    }
    return total;
  };

  const handleScoreChange = (playerId: string, value: string) => {
    setCurrentScores((prev) => ({ ...prev, [playerId]: value }));
  };

  const handleDetailedScoreChange = (
    playerId: string,
    categoryId: string,
    value: string,
  ) => {
    setDetailedScores((prev) => ({
      ...prev,
      [playerId]: {
        ...(prev[playerId] || {}),
        [categoryId]: value,
      },
    }));
  };

  const handleValidateRound = async () => {
    const scores: RoundScore[] = activeSession.players.map((p) => {
      // For games with categories (like Harmonies), we store the sum as the main score
      // and keep the details in the `details` object
      if (categories) {
        const pDetails = detailedScores[p.id] || {};
        let total = 0;
        for (const key in pDetails) {
          const val = parseInt(pDetails[key] || "0", 10);
          if (!isNaN(val)) total += val;
        }
        return {
          playerId: p.id,
          score: total,
          details: pDetails, // <--- This saves all category scores!
        };
      }

      // For standard games (Azul, Cabo, Odin)
      let val = parseInt(currentScores[p.id] || "0", 10);
      val = isNaN(val) ? 0 : val;

      // Kamikaze Rule Override (Cabo)
      if (kamikazePlayer) {
        if (p.id === kamikazePlayer) {
          val = 0; // Kamikaze player gets 0 points
        } else {
          val = 50; // Everyone else gets 50 points
        }
      }

      return {
        playerId: p.id,
        score: val,
        caboCall: caboCalls[p.id] || undefined,
        kamikaze: p.id === kamikazePlayer || undefined,
      };
    });

    await addRound(scores);
    setCurrentScores({}); // reset inputs
    setDetailedScores({}); // reset detailed inputs
    setCaboCalls({}); // reset cabo calls
    setKamikazePlayer(null); // reset kamikaze
    setCurrentCategoryIndex(0); // Reset wizard
  };

  const handleEndGame = async () => {
    // Determine winner based on scoreType
    const totals = activeSession.players.map((p) => ({
      id: p.id,
      score: calculateTotalScore(p.id),
    }));
    let winnerIds: string[] = [];

    if (totals.length > 0) {
      if (gameConfig.scoreType === "negative") {
        const minScore = Math.min(...totals.map((t) => t.score));
        winnerIds = totals.filter((t) => t.score === minScore).map((t) => t.id);
      } else {
        const maxScore = Math.max(...totals.map((t) => t.score));
        winnerIds = totals.filter((t) => t.score === maxScore).map((t) => t.id);
      }
    }

    await finishGame(winnerIds);
    navigate(`/gameover/${activeSession.id}`);
  };

  const handleCancelGame = async () => {
    if (
      window.confirm(
        "Êtes-vous sûr de vouloir annuler et supprimer cette partie ?",
      )
    ) {
      await db.sessions.delete(activeSession.id);
      navigate("/");
    }
  };

  const currentRoundNum = activeSession.rounds.length + 1;
  const isSingleRound = gameConfig?.fixedRounds === 1;

  return (
    <div className="relative flex flex-col min-h-screen pb-32 font-sans selection:bg-white/30 z-10">
      {/* Floating Top Bar (Header replacement) */}
      <div className="relative z-50 pt-12 px-4 pb-2 flex items-start justify-between w-full max-w-xl mx-auto">
        <div className="flex items-center bg-background/40 backdrop-blur-md rounded-full shadow-sm p-1.5 border border-black/5 dark:border-white/5">
          <button
            onClick={() => navigate("/")}
            className="active:scale-95 transition-transform"
            aria-label="Accueil"
          >
            <PlanetMark size={26} />
          </button>
        </div>

        <div className="text-center flex-1 flex flex-col items-center pointer-events-none mt-1">
          <div className="flex items-center justify-center gap-2 mb-1.5">
            {gameConfig?.imagePath ? (
              <div className="w-8 h-8 rounded-full overflow-hidden bg-background/60 backdrop-blur-sm p-1 shadow-sm border border-black/5 dark:border-white/5">
                <img
                  src={gameConfig.imagePath}
                  alt="Logo"
                  className="w-full h-full object-contain"
                />
              </div>
            ) : Icon ? (
              <div className="w-8 h-8 rounded-full bg-background/60 backdrop-blur-sm flex items-center justify-center shadow-sm border border-black/5 dark:border-white/5">
                <Icon
                  className="w-5 h-5 text-primary drop-shadow-sm"
                  strokeWidth={2.5}
                />
              </div>
            ) : null}
            <h1 className="text-2xl font-black tracking-tighter truncate drop-shadow-sm">
              {gameConfig?.name}
            </h1>
          </div>
          <div className="bg-primary/20 text-primary backdrop-blur-md border border-primary/20 px-4 py-1.5 rounded-full text-xs font-black uppercase tracking-widest shadow-sm">
            {isSingleRound ? "Décompte final" : `Manche ${currentRoundNum}`}
          </div>
        </div>

        <div className="shrink-0 flex items-center bg-background/40 rounded-full backdrop-blur-md p-0.5 shadow-sm border border-black/5 dark:border-white/5">
          {gameConfig?.rulesUrl && (
            <Button
              variant="ghost"
              size="icon"
              onClick={() => window.open(gameConfig.rulesUrl, "_blank")}
              className="text-blue-500 hover:bg-blue-500/20 rounded-full transition-colors w-10 h-10"
              title="Consulter les règles"
            >
              <BookOpen className="w-5 h-5" />
            </Button>
          )}
          <Button
            variant="ghost"
            size="icon"
            onClick={handleCancelGame}
            className="text-destructive hover:bg-destructive/20 rounded-full transition-colors w-10 h-10"
            title="Annuler la partie"
          >
            <Trash2 className="w-5 h-5" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            onClick={handleEndGame}
            className="text-primary hover:bg-primary/20 rounded-full transition-colors w-10 h-10"
            title="Terminer la partie"
          >
            <Award className="w-5 h-5" />
          </Button>
        </div>
      </div>

      <main className="flex-1 p-4 space-y-8 mt-2">
        {/* Leaderboard Summary (Floating Chips) */}
        <div className="flex overflow-x-auto pb-4 -mx-4 px-4 space-x-3 hide-scrollbar">
          {displayPlayers.map((player) => {
            const total = getLiveTotalScore(player.id);
            return (
              <motion.div
                key={player.id}
                className="shrink-0 flex items-center bg-background/80 backdrop-blur-xl rounded-full p-1.5 pr-4 shadow-sm border border-black/5 dark:border-white/5"
                initial={{ opacity: 0, scale: 0.8 }}
                animate={{ opacity: 1, scale: 1 }}
              >
                <div className="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center mr-3 border border-primary/20 text-primary font-black text-lg">
                  {total}
                </div>
                <div className="text-sm font-bold truncate max-w-[80px]">
                  {player.name}
                </div>
              </motion.div>
            );
          })}
        </div>

        {/* Current Round Input Section */}
        <section className="relative">
          <div className="flex items-center justify-between px-2 mb-4">
            <div className="flex items-center gap-2.5 min-w-0">
              {categories &&
                (() => {
                  const cat = categories[currentCategoryIndex];
                  const CatIcon = cat.icon ? (Icons as any)[cat.icon] : null;
                  return CatIcon ? (
                    <span
                      className="w-11 h-11 rounded-2xl grid place-items-center shrink-0 shadow-sm"
                      style={{
                        backgroundColor: `${cat.color ?? "#14b8a6"}22`,
                        color: cat.color ?? "#14b8a6",
                      }}
                    >
                      <CatIcon className="w-6 h-6" strokeWidth={2.2} />
                    </span>
                  ) : null;
                })()}
              <h2 className="text-2xl font-black tracking-tighter drop-shadow-sm truncate">
                {categories
                  ? categories[currentCategoryIndex].label
                  : isSingleRound
                    ? "Saisie des scores"
                    : "À vos marques !"}
              </h2>
            </div>
            <div className="flex items-center gap-2">
              {categories && currentCategoryIndex > 0 && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setCurrentCategoryIndex((prev) => prev - 1)}
                  className="rounded-full font-bold h-9 bg-background/50 backdrop-blur-sm border-0 shadow-sm"
                >
                  <Undo2 className="w-4 h-4 mr-1.5" />
                  Retour
                </Button>
              )}
              {activeSession.rounds.length > 0 &&
                !isSingleRound &&
                !categories && (
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={undoLastRound}
                    className="rounded-full font-bold h-9 bg-background/50 backdrop-blur-sm border-0 shadow-sm text-muted-foreground"
                  >
                    <Undo2 className="w-4 h-4 mr-1.5" />
                    Annuler manche
                  </Button>
                )}
              {categories && (
                <span className="text-xs font-black bg-primary/10 text-primary px-3 py-1.5 rounded-full">
                  Étape {currentCategoryIndex + 1} /{" "}
                  {categories.length}
                </span>
              )}
            </div>
          </div>

          {categories ? (
            <Card className="bg-background/80 backdrop-blur-xl border-0 shadow-xl rounded-[2.5rem] overflow-hidden">
              <CardContent className="p-4 space-y-1">
                {displayPlayers.map((player, idx) => {
                  const pDetails = detailedScores[player.id] || {};
                  const catId =
                    categories![currentCategoryIndex].id;

                  return (
                    <div
                      key={player.id}
                      className={`flex items-center justify-between gap-4 p-3 rounded-2xl transition-colors ${idx % 2 === 0 ? "bg-secondary/30" : "bg-transparent"}`}
                    >
                      <label className="font-bold flex-1 truncate text-lg ml-2">
                        {player.name}
                      </label>
                      <div className="w-32">
                        <Input
                          type="number"
                          inputMode="numeric"
                          pattern="[0-9]*"
                          placeholder="0"
                          className="text-center text-xl font-black h-14 bg-background border-none shadow-sm rounded-[1rem] focus-visible:ring-2 focus-visible:ring-primary"
                          value={pDetails[catId] || ""}
                          onChange={(e) =>
                            handleDetailedScoreChange(
                              player.id,
                              catId,
                              e.target.value,
                            )
                          }
                        />
                      </div>
                    </div>
                  );
                })}
              </CardContent>
            </Card>
          ) : (
            <Card className="bg-background/80 backdrop-blur-xl border-0 shadow-xl rounded-[2.5rem] overflow-hidden">
              <CardContent className="p-4 space-y-1">
                {displayPlayers.map((player, idx) => (
                  <div
                    key={player.id}
                    className={`flex flex-col pb-3 rounded-2xl p-3 transition-colors ${idx % 2 === 0 ? "bg-secondary/30" : "bg-transparent"}`}
                  >
                    <div className="flex items-center justify-between gap-4">
                      <label className="font-bold flex-1 truncate text-lg ml-2">
                        {player.name}
                      </label>
                      <div className="w-32">
                        <Input
                          type="number"
                          inputMode="numeric"
                          pattern="[0-9]*"
                          placeholder="0"
                          className="text-center text-xl font-black h-14 bg-background border-none shadow-sm rounded-[1rem] focus-visible:ring-2 focus-visible:ring-primary"
                          value={currentScores[player.id] || ""}
                          onChange={(e) =>
                            handleScoreChange(player.id, e.target.value)
                          }
                        />
                      </div>
                    </div>
                    {gameConfig.id === "cabo" && (
                      <div className="flex justify-end mt-3 gap-2 flex-wrap pr-1">
                        {/* We check activeSession.options, but also fallback to true if undefined as it's the default */}
                        {activeSession.options?.kamikaze !== false && (
                          <Button
                            variant={
                              kamikazePlayer === player.id
                                ? "default"
                                : "outline"
                            }
                            size="sm"
                            className={`h-9 px-4 rounded-full text-xs font-bold transition-all border-0 shadow-sm ${kamikazePlayer === player.id ? "bg-amber-500 hover:bg-amber-600 text-white" : "bg-background text-muted-foreground hover:bg-amber-500/10"}`}
                            onClick={() =>
                              setKamikazePlayer(
                                kamikazePlayer === player.id ? null : player.id,
                              )
                            }
                          >
                            Kamikaze
                          </Button>
                        )}
                        <Button
                          variant={
                            caboCalls[player.id] === "success"
                              ? "default"
                              : "outline"
                          }
                          size="sm"
                          className={`h-9 px-4 rounded-full text-xs font-bold transition-all border-0 shadow-sm ${caboCalls[player.id] === "success" ? "bg-green-500 hover:bg-green-600 text-white" : "bg-background text-muted-foreground hover:bg-green-500/10"}`}
                          onClick={() =>
                            setCaboCalls((prev) => ({
                              ...prev,
                              [player.id]:
                                prev[player.id] === "success"
                                  ? null
                                  : "success",
                            }))
                          }
                        >
                          Cabo +
                        </Button>
                        <Button
                          variant={
                            caboCalls[player.id] === "fail"
                              ? "destructive"
                              : "outline"
                          }
                          size="sm"
                          className={`h-9 px-4 rounded-full text-xs font-bold transition-all border-0 shadow-sm ${caboCalls[player.id] === "fail" ? "bg-red-500 hover:bg-red-600 text-white" : "bg-background text-muted-foreground hover:bg-red-500/10"}`}
                          onClick={() =>
                            setCaboCalls((prev) => ({
                              ...prev,
                              [player.id]:
                                prev[player.id] === "fail" ? null : "fail",
                            }))
                          }
                        >
                          Cabo -
                        </Button>
                      </div>
                    )}
                  </div>
                ))}
              </CardContent>
            </Card>
          )}
        </section>

        {/* History Preview */}
        {activeSession.rounds.length > 0 && (
          <section className="space-y-4 pt-4">
            <h3 className="text-lg font-black tracking-tight px-2 text-foreground/80">
              Historique récent
            </h3>
            <div className="space-y-3">
              {activeSession.rounds
                .slice()
                .reverse()
                .slice(0, 3)
                .map((round, index) => (
                  <motion.div
                    key={round.id}
                    initial={{ opacity: 0, x: -20 }}
                    animate={{ opacity: 1, x: 0 }}
                    transition={{ delay: index * 0.1 }}
                    className="flex items-center justify-between p-4 rounded-[1.5rem] bg-background/50 backdrop-blur-md shadow-sm border border-black/5 dark:border-white/5"
                  >
                    <div className="bg-foreground/10 text-foreground font-black px-3 py-1 rounded-lg text-sm mr-4">
                      #{round.roundNumber}
                    </div>
                    <div className="flex-1 flex justify-around items-center">
                      {round.scores.map((s) => (
                        <div
                          key={s.playerId}
                          className="flex flex-col items-center"
                        >
                          <span
                            className={`font-black text-lg ${s.score > 0 ? "text-primary" : s.score < 0 ? "text-destructive" : "text-muted-foreground"}`}
                          >
                            {s.score > 0 ? `+${s.score}` : s.score}
                          </span>
                          {s.caboCall === "success" && (
                            <span className="text-[10px] bg-green-500/20 text-green-700 dark:text-green-400 px-1.5 py-0.5 rounded font-bold mt-1 uppercase tracking-wider">
                              Cabo+
                            </span>
                          )}
                          {s.caboCall === "fail" && (
                            <span className="text-[10px] bg-red-500/20 text-red-700 dark:text-red-400 px-1.5 py-0.5 rounded font-bold mt-1 uppercase tracking-wider">
                              Cabo-
                            </span>
                          )}
                          {s.kamikaze && (
                            <span className="text-[10px] bg-amber-500/20 text-amber-700 dark:text-amber-400 px-1.5 py-0.5 rounded font-bold mt-1 uppercase tracking-wider">
                              Kamikaze
                            </span>
                          )}
                        </div>
                      ))}
                    </div>
                  </motion.div>
                ))}
            </div>
          </section>
        )}
      </main>

      <div className="fixed bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-background via-background/90 to-transparent z-30 pb-safe pointer-events-none">
        <div className="max-w-md mx-auto pointer-events-auto">
          <Button
            size="lg"
            className="w-full text-xl font-black shadow-xl h-16 rounded-[2rem] transition-transform active:scale-95"
            onClick={() => {
              if (
                categories &&
                currentCategoryIndex < categories.length - 1
              ) {
                setCurrentCategoryIndex((prev) => prev + 1);
              } else {
                handleValidateRound();
              }
            }}
          >
            {categories &&
            currentCategoryIndex < categories.length - 1 ? (
              "Suivant"
            ) : (
              <>
                <Check className="w-7 h-7 mr-2" strokeWidth={3} />
                {categories || isSingleRound
                  ? "Valider le score"
                  : "Valider la manche"}
              </>
            )}
          </Button>
        </div>
      </div>
    </div>
  );
}
