import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useState, useCallback, useRef } from "react";
import { useWsClient, useWsConnected } from "../../lib/ws-hooks.js";
import type {
  Lobby,
  WsLobbyState,
  WsError,
  WsGameQuestion,
} from "@lila/shared";

export const Route = createFileRoute("/multiplayer/lobby/$code")({
  component: LobbyPage,
});

function LobbyPage() {
  const { code } = Route.useParams();
  const { session } = Route.useRouteContext();
  const currentUserId = session.user.id;
  const navigate = useNavigate();
  const client = useWsClient();
  const isConnected = useWsConnected();

  const [lobby, setLobby] = useState<Lobby | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [isStarting, setIsStarting] = useState(false);
  const lobbyIdRef = useRef<string | null>(null);

  const handleLobbyState = useCallback((msg: WsLobbyState) => {
    setLobby(msg.lobby);
    lobbyIdRef.current = msg.lobby.id;
    setError(null);
  }, []);

  const handleGameQuestion = useCallback(
    (_msg: WsGameQuestion) => {
      void navigate({
        to: "/multiplayer/game/$code",
        params: { code },
        search: { lobbyId: lobbyIdRef.current ?? "" },
      });
    },
    [navigate, code],
  );

  const handleWsError = useCallback((msg: WsError) => {
    setError(msg.message);
    setIsStarting(false);
  }, []);

  useEffect(() => {
    if (!isConnected) return;

    client.on("lobby:state", handleLobbyState);
    client.on("game:question", handleGameQuestion);
    client.on("error", handleWsError);

    client.send({ type: "lobby:join", code });

    return () => {
      client.off("lobby:state", handleLobbyState);
      client.off("game:question", handleGameQuestion);
      client.off("error", handleWsError);
      if (lobbyIdRef.current) {
        client.send({ type: "lobby:leave", lobbyId: lobbyIdRef.current });
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isConnected]);

  const handleStart = useCallback(() => {
    if (!lobby) return;
    setIsStarting(true);
    client.send({ type: "lobby:start", lobbyId: lobby.id });
  }, [lobby, client]);

  if (!isConnected || !lobby) {
    return (
      <div className="min-h-screen bg-linear-to-b from-purple-100 to-pink-50 flex items-center justify-center">
        <p className="text-purple-400 text-lg font-medium">
          {error ?? (isConnected ? "Joining lobby..." : "Connecting...")}
        </p>
      </div>
    );
  }

  const isHost = lobby.hostUserId === currentUserId;
  const canStart = isHost && lobby.players.length >= 2 && !isStarting;

  return (
    <div className="min-h-screen bg-linear-to-b from-purple-100 to-pink-50 flex items-center justify-center p-6">
      <div className="w-full max-w-md rounded-3xl border border-(--color-primary-light) bg-white/50 dark:bg-black/10 backdrop-blur shadow-sm p-8 flex flex-col gap-6">
        {/* Lobby code */}
        <div className="flex flex-col items-center gap-2">
          <p className="text-xs font-bold tracking-widest uppercase text-(--color-text-muted)">
            Lobby code
          </p>
          <button
            className="text-4xl font-black tracking-widest text-(--color-text) hover:text-(--color-primary) cursor-pointer"
            onClick={() => {
              void navigator.clipboard.writeText(code);
            }}
            title="Click to copy"
          >
            {code}
          </button>
          <p className="text-xs text-(--color-text-muted)">Click to copy</p>
        </div>

        <div className="border-t border-(--color-primary-light) opacity-60" />

        {/* Player list */}
        <div className="flex flex-col gap-2">
          <h2 className="text-lg font-black text-(--color-text)">
            Players ({lobby.players.length})
          </h2>
          <ul className="flex flex-col gap-1">
            {lobby.players.map((player) => (
              <li
                key={player.userId}
                className="flex items-center gap-2 text-sm text-(--color-text)"
              >
                <span className="w-2 h-2 rounded-full bg-green-400" />
                {player.user.name}
                {player.userId === lobby.hostUserId && (
                  <span className="text-xs text-purple-500 font-medium">
                    host
                  </span>
                )}
              </li>
            ))}
          </ul>
        </div>

        {/* Error */}
        {error && <p className="text-red-500 text-sm text-center">{error}</p>}

        {/* Start button — host only */}
        {isHost && (
          <button
            className="rounded-2xl bg-(--color-primary) px-4 py-3 text-white font-black hover:bg-(--color-primary-dark) shadow-sm hover:shadow-md transition-all disabled:opacity-50"
            onClick={handleStart}
            disabled={!canStart}
          >
            {isStarting
              ? "Starting..."
              : lobby.players.length < 2
                ? "Waiting for players..."
                : "Start Game"}
          </button>
        )}

        {/* Non-host waiting message */}
        {!isHost && (
          <p className="text-sm text-(--color-text-muted) text-center">
            Waiting for host to start the game...
          </p>
        )}
      </div>
    </div>
  );
}
