import { useState } from "react";
import { useLiveQuery } from "dexie-react-hooks";
import { db } from "../database/db";
import { useProfileStore } from "../stores/profileStore";
import {
  Users,
  Trash2,
  Edit2,
  Check,
  X,
  Camera,
  Dices,
  Loader2,
} from "lucide-react";
import { Card, CardContent } from "../components/ui/card";
import { Button } from "../components/ui/button";
import { Input } from "../components/ui/input";
import { PageHeader } from "../components/PageHeader";
import { Avatar } from "../components/ui/avatar";
import { resizeImage } from "../utils/image";
import { motion } from "framer-motion";

export default function Players() {
  const activeProfileId = useProfileStore((s) => s.activeProfileId);
  const players = useLiveQuery(
    async () => {
      if (!activeProfileId) return [];
      return db.players
        .where("profileId")
        .equals(activeProfileId)
        .and((p) => !p.deletedAt)
        .sortBy("name");
    },
    [activeProfileId],
  );
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editName, setEditName] = useState("");
  const [isGenerating, setIsGenerating] = useState<string | null>(null);

  const handleDelete = async (id: string, name: string) => {
    if (window.confirm(`Êtes-vous sûr de vouloir supprimer ${name} ?`)) {
      // Soft-delete (tombstone) so the deletion can propagate to the server.
      await db.players.update(id, { deletedAt: Date.now() });
    }
  };

  const startEdit = (id: string, name: string) => {
    setEditingId(id);
    setEditName(name);
  };

  const saveEdit = async (id: string) => {
    if (editName.trim()) {
      const newName = editName.trim();
      const playerToEdit = players?.find((p) => p.id === id);

      await db.players.update(id, { name: newName, updatedAt: Date.now() });

      // Update the player's name in this profile's game sessions (history).
      // Scoped by profile so a same-named player in another profile is untouched.
      const sessions = activeProfileId
        ? await db.sessions
            .where("profileId")
            .equals(activeProfileId)
            .toArray()
        : [];
      const updatedSessions = sessions
        .map((session) => {
          let hasChanges = false;
          const newPlayers = session.players.map((p) => {
            // Check by ID or fallback to exact name matching if older data
            if (p.id === id || (playerToEdit && p.name === playerToEdit.name)) {
              hasChanges = true;
              return { ...p, name: newName };
            }
            return p;
          });

          if (hasChanges) {
            return { ...session, players: newPlayers };
          }
          return null;
        })
        .filter((s) => s !== null) as typeof sessions;

      if (updatedSessions.length > 0) {
        await db.sessions.bulkPut(updatedSessions);
      }
    }
    setEditingId(null);
  };

  const updatePlayerAvatarGlobally = async (
    playerId: string,
    avatarData: string,
  ) => {
    await db.players.update(playerId, {
      avatar: avatarData,
      updatedAt: Date.now(),
    });

    // Update historical sessions too if we want the avatar to reflect immediately everywhere
    const sessions = activeProfileId
      ? await db.sessions.where("profileId").equals(activeProfileId).toArray()
      : [];
    const updatedSessions = sessions
      .map((session) => {
        let hasChanges = false;
        const newPlayers = session.players.map((p) => {
          if (p.id === playerId) {
            hasChanges = true;
            return { ...p, avatar: avatarData };
          }
          return p;
        });
        if (hasChanges) return { ...session, players: newPlayers };
        return null;
      })
      .filter((s) => s !== null) as typeof sessions;

    if (updatedSessions.length > 0) {
      await db.sessions.bulkPut(updatedSessions);
    }
  };

  const handleAvatarChange = async (
    playerId: string,
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    const file = event.target.files?.[0];
    if (!file) return;

    try {
      const base64Image = await resizeImage(file);
      await updatePlayerAvatarGlobally(playerId, base64Image);
    } catch (e) {
      alert("Erreur lors de l'enregistrement de l'image.");
    }
  };

  const handleGenerateRandomAvatar = async (playerId: string) => {
    setIsGenerating(playerId);
    try {
      // Seed aléatoire
      const seed = Math.random().toString(36).substring(7);
      // Utilisation du style "bottts-neutral"
      const url = `https://api.dicebear.com/9.x/bottts-neutral/svg?seed=${seed}`;

      const response = await fetch(url);
      const svgText = await response.text();

      // On encode l'SVG proprement pour l'utiliser comme image dans l'app
      const encodedSvg = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;

      await updatePlayerAvatarGlobally(playerId, encodedSvg);
    } catch (e) {
      alert(
        "Impossible de générer l'avatar. Vérifiez votre connexion internet.",
      );
    } finally {
      setIsGenerating(null);
    }
  };

  return (
    <div className="p-5 space-y-5 relative z-10">
      <PageHeader title="Joueurs" />

      <div className="space-y-4">
        {!players || players.length === 0 ? (
          <div className="text-center text-muted-foreground py-12 flex flex-col items-center bg-background/60 backdrop-blur-sm rounded-[2rem]">
            <Users className="w-16 h-16 mb-4 opacity-20" />
            <p className="font-bold text-lg">Aucun joueur enregistré.</p>
            <p className="text-sm mt-1 max-w-[250px]">
              Ils s'ajouteront automatiquement lors de votre prochaine partie.
            </p>
          </div>
        ) : (
          players.map((player, index) => (
            <motion.div
              key={player.id}
              initial={{ opacity: 0, x: -20 }}
              animate={{ opacity: 1, x: 0 }}
              transition={{
                delay: index * 0.05,
                type: "spring",
                stiffness: 100,
              }}
            >
              <Card className="border-0 shadow-lg bg-background/90 backdrop-blur-md overflow-visible relative group">
                {/* Decorative blob */}
                <div className="absolute -left-2 -top-2 w-8 h-8 rounded-full bg-primary/20 blur-md pointer-events-none group-hover:bg-primary/40 transition-colors" />

                <CardContent className="p-4 flex items-center justify-between">
                  {editingId === player.id ? (
                    <div className="flex items-center space-x-2 flex-1 mr-2 relative z-10">
                      <Input
                        value={editName}
                        onChange={(e) => setEditName(e.target.value)}
                        className="h-12"
                        autoFocus
                      />
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => saveEdit(player.id)}
                        className="text-green-600 bg-green-500/10 hover:bg-green-500/20"
                      >
                        <Check className="w-6 h-6" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => setEditingId(null)}
                        className="text-muted-foreground bg-black/5 hover:bg-black/10 dark:bg-white/5 dark:hover:bg-white/10"
                      >
                        <X className="w-6 h-6" />
                      </Button>
                    </div>
                  ) : (
                    <>
                      <div className="flex flex-col items-center mr-4 shrink-0 gap-1.5">
                        <div
                          className="relative group/avatar cursor-pointer"
                          onClick={() => {
                            const input = document.getElementById(
                              `avatar-upload-${player.id}`,
                            );
                            input?.click();
                          }}
                        >
                          <Avatar
                            src={player.avatar}
                            name={player.name}
                            size="lg"
                            className="shadow-md border-4 border-background"
                          />
                          <div className="absolute inset-0 bg-black/40 rounded-full flex items-center justify-center opacity-0 group-hover/avatar:opacity-100 transition-opacity">
                            <Camera className="w-5 h-5 text-white" />
                          </div>
                          <input
                            type="file"
                            id={`avatar-upload-${player.id}`}
                            className="hidden"
                            accept="image/*"
                            onChange={(e) => handleAvatarChange(player.id, e)}
                          />
                        </div>
                        <Button
                          variant="ghost"
                          size="sm"
                          disabled={isGenerating === player.id}
                          className="h-6 px-3 rounded-full text-[10px] font-black uppercase tracking-wider bg-primary/10 text-primary hover:bg-primary/20 transition-colors"
                          onClick={() => handleGenerateRandomAvatar(player.id)}
                        >
                          {isGenerating === player.id ? (
                            <Loader2 className="w-3 h-3 mr-1 animate-spin" />
                          ) : (
                            <Dices className="w-3 h-3 mr-1" />
                          )}
                          Aléatoire
                        </Button>
                      </div>
                      <span className="font-black text-xl truncate flex-1 tracking-tight">
                        {player.name}
                      </span>
                      <div className="flex items-center shrink-0 space-x-1 relative z-10">
                        <Button
                          variant="ghost"
                          size="icon"
                          onClick={() => startEdit(player.id, player.name)}
                          className="text-muted-foreground hover:bg-black/5 dark:hover:bg-white/5"
                        >
                          <Edit2 className="w-5 h-5" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          onClick={() => handleDelete(player.id, player.name)}
                          className="text-destructive hover:bg-destructive/10"
                        >
                          <Trash2 className="w-5 h-5" />
                        </Button>
                      </div>
                    </>
                  )}
                </CardContent>
              </Card>
            </motion.div>
          ))
        )}
      </div>
    </div>
  );
}
