import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import {
  ChevronLeft,
  Plus,
  X,
  Play,
  Users,
  GripVertical,
  BookOpen,
  MapPin,
} from "lucide-react";
import * as Icons from "lucide-react";
import { useLiveQuery } from "dexie-react-hooks";
import { Reorder, useDragControls } from "framer-motion";
import { db } from "../database/db";
import { useGameConfig } from "../games";
import { useGameStore } from "../stores/gameStore";
import { useProfileStore } from "../stores/profileStore";
import { useAuthStore } from "../stores/authStore";
import { useFriendsStore, FriendEntry } from "../stores/friendsStore";
import { useGameTheme } from "../hooks/useGameTheme";
import { Player, SavedPlayer } from "../types";
import { Button } from "../components/ui/button";
import { Input } from "../components/ui/input";
import { Card, CardContent } from "../components/ui/card";
import { Avatar } from "../components/ui/avatar";
import { PlanetMark } from "../components/Logo";
import { generateId } from "../utils/id";

function DraggablePlayerItem({
  player,
  index,
  avatar,
  canRemove,
  updatePlayerName,
  handleRemovePlayer,
}: any) {
  const controls = useDragControls();

  return (
    <Reorder.Item
      value={player}
      dragListener={false}
      dragControls={controls}
      className="flex items-center space-x-2 bg-background/60 backdrop-blur-sm border shadow-sm relative rounded-2xl w-full p-2 pr-3"
    >
      <div
        className="p-2 cursor-grab active:cursor-grabbing touch-none"
        onPointerDown={(e) => controls.start(e)}
      >
        <GripVertical className="w-5 h-5 text-muted-foreground opacity-50 hover:opacity-100 transition-opacity" />
      </div>
      {avatar && (
        <Avatar
          src={avatar}
          name={player.name}
          size="md"
          className="shrink-0 border-2 border-background shadow-sm"
        />
      )}
      <Input
        value={player.name}
        onChange={(e) => updatePlayerName(player.id, e.target.value)}
        placeholder={`Joueur ${index + 1}`}
        className="flex-1 bg-transparent border-0 focus-visible:ring-0 focus-visible:ring-offset-0 font-bold text-lg px-2"
      />
      {canRemove && (
        <Button
          variant="ghost"
          size="icon"
          onClick={() => handleRemovePlayer(player.id)}
          className="text-destructive shrink-0 hover:bg-destructive/10 rounded-xl"
        >
          <X className="w-5 h-5" />
        </Button>
      )}
    </Reorder.Item>
  );
}

export default function NewGame() {
  const { gameId } = useParams<{ gameId: string }>();
  const navigate = useNavigate();
  const gameConfig = useGameConfig(gameId);
  useGameTheme(gameConfig);

  const startNewGame = useGameStore((state) => state.startNewGame);
  const activeProfileId = useProfileStore((state) => state.activeProfileId);
  const authStatus = useAuthStore((state) => state.status);
  const { friends, load: loadFriends } = useFriendsStore();

  useEffect(() => {
    if (authStatus === "authenticated") loadFriends();
  }, [authStatus, loadFriends]);

  const [players, setPlayers] = useState<Player[]>([
    { id: generateId(), name: "" },
    { id: generateId(), name: "" },
  ]);
  const [options, setOptions] = useState<Record<string, any>>({});
  const [locationId, setLocationId] = useState<string | undefined>(undefined);

  const savedPlayers =
    useLiveQuery(
      async () => {
        if (!activeProfileId) return [];
        return db.players
          .where("profileId")
          .equals(activeProfileId)
          .and((p) => !p.deletedAt)
          .sortBy("name");
      },
      [activeProfileId],
    ) || [];
  const locations =
    useLiveQuery(
      async () => {
        if (!activeProfileId) return [];
        return db.locations
          .where("profileId")
          .equals(activeProfileId)
          .and((l) => !l.deletedAt)
          .sortBy("name");
      },
      [activeProfileId],
    ) || [];
  const availableSavedPlayers = savedPlayers.filter(
    (sp) =>
      !players.some(
        (p) => p.name.trim().toLowerCase() === sp.name.trim().toLowerCase(),
      ),
  );
  const availableFriends = friends.filter(
    (f) => !players.some((p) => p.linkedUserId === f.user.id),
  );

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

  const handleAddPlayer = () => {
    if (players.length < gameConfig.maxPlayers) {
      setPlayers([...players, { id: generateId(), name: "" }]);
    }
  };

  const handleQuickAdd = (savedPlayer: SavedPlayer) => {
    // Fill the first empty input if any
    const emptyIndex = players.findIndex((p) => p.name.trim() === "");
    if (emptyIndex !== -1) {
      const newPlayers = [...players];
      newPlayers[emptyIndex] = {
        id: savedPlayer.id,
        name: savedPlayer.name,
        avatar: savedPlayer.avatar,
      };
      setPlayers(newPlayers);
    } else if (players.length < gameConfig.maxPlayers) {
      // Add a new slot if we have room
      setPlayers([
        ...players,
        {
          id: savedPlayer.id,
          name: savedPlayer.name,
          avatar: savedPlayer.avatar,
        },
      ]);
    }
  };

  const handleQuickAddFriend = (friend: FriendEntry) => {
    // Snapshot the friend's name/avatar into the session, tagged with their
    // server account id (linkedUserId).
    const newPlayer: Player = {
      id: generateId(),
      name: friend.user.displayName,
      avatar: friend.user.avatarUrl ?? undefined,
      linkedUserId: friend.user.id,
    };
    const emptyIndex = players.findIndex((p) => p.name.trim() === "");
    if (emptyIndex !== -1) {
      const newPlayers = [...players];
      newPlayers[emptyIndex] = newPlayer;
      setPlayers(newPlayers);
    } else if (players.length < gameConfig.maxPlayers) {
      setPlayers([...players, newPlayer]);
    }
  };

  const handleRemovePlayer = (id: string) => {
    if (players.length > gameConfig.minPlayers) {
      setPlayers(players.filter((p) => p.id !== id));
    }
  };

  const updatePlayerName = (id: string, name: string) => {
    setPlayers(players.map((p) => (p.id === id ? { ...p, name } : p)));
  };

  const handleStart = async () => {
    if (!activeProfileId) return;

    // Basic validation
    const validPlayers = players.filter((p) => p.name.trim() !== "");
    if (validPlayers.length < gameConfig.minPlayers) {
      alert(`Il faut au moins ${gameConfig.minPlayers} joueurs avec un nom.`);
      return;
    }

    // Auto-save new players and generate avatar if missing
    const playersToSave = [...validPlayers];

    for (let i = 0; i < playersToSave.length; i++) {
      const p = playersToSave[i];
      const exists = await db.players
        .where("name")
        .equalsIgnoreCase(p.name)
        .and((pl) => pl.profileId === activeProfileId && !pl.deletedAt)
        .first();

      if (!exists) {
        let finalAvatar = p.avatar;
        // Generate a random avatar automatically
        if (!finalAvatar) {
          try {
            const seed = Math.random().toString(36).substring(7);
            const url = `https://api.dicebear.com/9.x/bottts-neutral/svg?seed=${seed}`;
            const response = await fetch(url);
            const svgText = await response.text();
            finalAvatar = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
            // Update the player array we are passing to the game session
            playersToSave[i].avatar = finalAvatar;
          } catch (e) {
            console.error("Failed to generate auto-avatar");
          }
        }
        const now = Date.now();
        await db.players.add({
          id: p.id,
          name: p.name,
          createdAt: now,
          updatedAt: now,
          avatar: finalAvatar,
          profileId: activeProfileId,
        });
      }
    }

    const sessionId = await startNewGame(
      gameConfig.id,
      playersToSave,
      options,
      activeProfileId,
      locationId,
    );
    navigate(`/play/${sessionId}`);
  };

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

  return (
    <div className="relative flex flex-col font-sans pb-24 z-10">
      {/* Floating Top Bar (Header replacement) */}
      <div className="relative z-50 pt-12 px-4 flex items-center justify-between">
        <div className="flex items-center gap-1 bg-background/40 backdrop-blur-md rounded-full shadow-sm p-1 border border-black/5 dark:border-white/5">
          <button
            onClick={() => navigate("/")}
            className="active:scale-95 transition-transform shrink-0 ml-0.5"
            aria-label="Accueil"
          >
            <PlanetMark size={26} />
          </button>
          <Button
            variant="ghost"
            size="icon"
            className="rounded-full hover:bg-black/10 dark:hover:bg-white/10"
            onClick={() => navigate(-1)}
          >
            <ChevronLeft className="w-6 h-6" />
          </Button>
        </div>
      </div>

      {/* Hero Banner Description (Moved from header to body) */}
      <div className="w-full relative flex flex-col items-center justify-center py-6 mt-2">
        <div className="w-28 h-28 bg-background/90 backdrop-blur-sm rounded-[2rem] shadow-xl flex items-center justify-center mb-5 relative z-10 transform -rotate-3 border-4 border-primary/20 overflow-hidden">
          {gameConfig.imagePath ? (
            <img
              src={gameConfig.imagePath}
              alt={`Logo ${gameConfig.name}`}
              className="w-full h-full object-cover"
            />
          ) : Icon ? (
            <Icon
              className="w-14 h-14 text-primary drop-shadow-sm"
              strokeWidth={1.5}
            />
          ) : null}
        </div>

        <div className="text-center relative z-10 px-4 flex flex-col items-center">
          <p className="text-sm font-medium text-foreground/80 max-w-sm mx-auto bg-background/40 backdrop-blur-md py-2 px-6 rounded-full shadow-sm border border-black/5 dark:border-white/5 mb-4">
            {gameConfig.description}
          </p>

          {gameConfig.rulesUrl && (
            <Button
              variant="outline"
              size="sm"
              className="rounded-full bg-background/80 backdrop-blur-md border-primary/20 text-primary shadow-lg hover:bg-primary/10 transition-colors font-bold"
              onClick={() => window.open(gameConfig.rulesUrl, "_blank")}
            >
              <BookOpen className="w-4 h-4 mr-2" />
              Règles du jeu
            </Button>
          )}
        </div>
      </div>

      <main className="flex-1 p-4 space-y-8">
        <section className="space-y-4">
          <div className="flex items-center justify-between px-2">
            <h2 className="text-2xl font-black tracking-tighter drop-shadow-sm">
              Joueurs
            </h2>
            <span className="text-sm font-bold text-primary bg-primary/10 px-3 py-1 rounded-full">
              {players.length}/{gameConfig.maxPlayers}
            </span>
          </div>

          <Card className="bg-background/80 backdrop-blur-xl border-0 shadow-lg rounded-[2rem] p-3 overflow-hidden">
            <CardContent className="p-0">
              <Reorder.Group
                axis="y"
                values={players}
                onReorder={setPlayers}
                className="space-y-2"
              >
                {players.map((player, index) => {
                  const dbPlayer = savedPlayers.find((p) => p.id === player.id);
                  const avatar = player.avatar || dbPlayer?.avatar;
                  return (
                    <DraggablePlayerItem
                      key={player.id}
                      player={player}
                      index={index}
                      avatar={avatar}
                      canRemove={players.length > gameConfig.minPlayers}
                      updatePlayerName={updatePlayerName}
                      handleRemovePlayer={handleRemovePlayer}
                    />
                  );
                })}
              </Reorder.Group>

              {players.length < gameConfig.maxPlayers && (
                <Button
                  variant="outline"
                  className="w-full mt-3 border-dashed border-2 rounded-2xl h-14 font-bold text-muted-foreground hover:text-primary hover:border-primary/50 hover:bg-primary/5 transition-all"
                  onClick={handleAddPlayer}
                >
                  <Plus className="w-5 h-5 mr-2" />
                  Ajouter une place vide
                </Button>
              )}
            </CardContent>
          </Card>

          {availableSavedPlayers.length > 0 && (
            <div className="mt-6 pt-2 px-1">
              <p className="text-sm font-bold text-muted-foreground mb-3 flex items-center">
                <Users className="w-4 h-4 mr-2" /> Ajout rapide
              </p>
              <div className="flex flex-wrap gap-2">
                {availableSavedPlayers.map((sp) => (
                  <div
                    key={sp.id}
                    className="flex items-center bg-background/80 backdrop-blur-md hover:bg-primary/10 hover:text-primary px-3 py-2 rounded-full cursor-pointer active:scale-95 transition-all text-sm font-bold border-2 border-transparent hover:border-primary/20 shadow-sm"
                    onClick={() => handleQuickAdd(sp)}
                  >
                    {sp.avatar ? (
                      <Avatar
                        src={sp.avatar}
                        name={sp.name}
                        size="sm"
                        className="mr-2 border-none w-6 h-6 shadow-sm"
                      />
                    ) : (
                      <Plus className="w-4 h-4 mr-1.5 opacity-50" />
                    )}
                    {sp.name}
                  </div>
                ))}
              </div>
            </div>
          )}

          {availableFriends.length > 0 && (
            <div className="mt-6 pt-2 px-1">
              <p className="text-sm font-bold text-muted-foreground mb-3 flex items-center">
                <Users className="w-4 h-4 mr-2" /> Amis
              </p>
              <div className="flex flex-wrap gap-2">
                {availableFriends.map((f) => (
                  <div
                    key={f.user.id}
                    className="flex items-center bg-background/80 backdrop-blur-md hover:bg-primary/10 hover:text-primary px-3 py-2 rounded-full cursor-pointer active:scale-95 transition-all text-sm font-bold border-2 border-transparent hover:border-primary/20 shadow-sm"
                    onClick={() => handleQuickAddFriend(f)}
                  >
                    {f.user.avatarUrl ? (
                      <Avatar
                        src={f.user.avatarUrl}
                        name={f.user.displayName}
                        size="sm"
                        className="mr-2 border-none w-6 h-6 shadow-sm"
                      />
                    ) : (
                      <Plus className="w-4 h-4 mr-1.5 opacity-50" />
                    )}
                    {f.user.displayName}
                  </div>
                ))}
              </div>
            </div>
          )}
        </section>

        {locations.length > 0 && (
          <section className="space-y-4">
            <h2 className="text-2xl font-black tracking-tighter px-2 drop-shadow-sm">
              Lieu
            </h2>
            <div className="flex flex-wrap gap-2 px-1">
              <div
                className={`flex items-center px-3 py-2 rounded-full cursor-pointer active:scale-95 transition-all text-sm font-bold border-2 shadow-sm ${
                  !locationId
                    ? "bg-primary/10 text-primary border-primary/30"
                    : "bg-background/80 backdrop-blur-md border-transparent hover:border-primary/20"
                }`}
                onClick={() => setLocationId(undefined)}
              >
                <MapPin className="w-4 h-4 mr-1.5 opacity-50" />
                Aucun
              </div>
              {locations.map((loc) => (
                <div
                  key={loc.id}
                  className={`flex items-center px-3 py-2 rounded-full cursor-pointer active:scale-95 transition-all text-sm font-bold border-2 shadow-sm ${
                    locationId === loc.id
                      ? "bg-primary/10 text-primary border-primary/30"
                      : "bg-background/80 backdrop-blur-md border-transparent hover:border-primary/20"
                  }`}
                  onClick={() => setLocationId(loc.id)}
                >
                  <MapPin className="w-4 h-4 mr-1.5 opacity-50" />
                  {loc.name}
                </div>
              ))}
            </div>
          </section>
        )}

        {gameConfig.options && gameConfig.options.length > 0 && (
          <section className="space-y-4">
            <h2 className="text-2xl font-black tracking-tighter px-2 drop-shadow-sm">
              Options
            </h2>
            <Card className="bg-background/80 backdrop-blur-xl border-0 shadow-lg rounded-[2rem] overflow-hidden">
              <CardContent className="p-5 space-y-5">
                {gameConfig.options.map((opt) => (
                  <div
                    key={opt.id}
                    className="flex items-center justify-between"
                  >
                    <label htmlFor={opt.id} className="text-base font-bold">
                      {opt.label}
                    </label>
                    {opt.type === "boolean" && (
                      <input
                        type="checkbox"
                        id={opt.id}
                        className="w-6 h-6 accent-primary rounded-md cursor-pointer"
                        checked={options[opt.id] ?? opt.defaultValue}
                        onChange={(e) =>
                          setOptions({ ...options, [opt.id]: e.target.checked })
                        }
                      />
                    )}
                    {opt.type === "number" && (
                      <div
                        className={`transition-opacity ${opt.id === "custom_target_score" && options["target_score"] !== "custom" ? "opacity-30 pointer-events-none" : "opacity-100"}`}
                      >
                        <Input
                          type="number"
                          id={opt.id}
                          className="w-24 text-center font-bold text-lg rounded-2xl h-12 bg-black/5 dark:bg-white/5 border-none focus-visible:ring-primary"
                          value={options[opt.id] ?? opt.defaultValue}
                          onChange={(e) =>
                            setOptions({ ...options, [opt.id]: e.target.value })
                          }
                        />
                      </div>
                    )}
                    {opt.type === "select" && opt.options && (
                      <select
                        id={opt.id}
                        className="p-3 border-none shadow-sm font-bold rounded-2xl bg-black/5 dark:bg-white/5 cursor-pointer outline-none focus:ring-2 focus:ring-primary/50"
                        value={options[opt.id] ?? opt.defaultValue}
                        onChange={(e) =>
                          setOptions({ ...options, [opt.id]: e.target.value })
                        }
                      >
                        {opt.options.map((o) => (
                          <option key={o.value} value={o.value}>
                            {o.label}
                          </option>
                        ))}
                      </select>
                    )}
                  </div>
                ))}
              </CardContent>
            </Card>
          </section>
        )}
      </main>

      <div className="fixed bottom-0 left-0 right-0 p-4 bg-background/80 backdrop-blur-xl border-t z-20 pb-safe">
        <div className="max-w-md mx-auto">
          <Button
            size="lg"
            className="w-full text-xl font-black shadow-xl h-16 rounded-[2rem] transition-transform active:scale-95"
            onClick={handleStart}
          >
            <Play className="w-6 h-6 mr-3" fill="currentColor" />
            Commencer
          </Button>
        </div>
      </div>
    </div>
  );
}
