import React, { useEffect, useState, useCallback, useRef } from "react";
import MainMenu from "./views/MainMenu/MainMenu";
import GameInterface from "./views/GameInterface/GameInterface";
import LoadingScreen from "./views/LoadingScreen/LoadingScreen.jsx";
import GameDataManager from "./services/GameDataManager";
import { useAuth } from "./hooks/useAuth";
import { useSocket } from "./hooks/useSocket";

function App() {
  const { isConnected, connectToServer, socket } = useSocket();
  const { user } = useAuth();

  const [isInGame, setIsInGame] = useState(false);
  const [isBooting, setIsBooting] = useState(false);
  const [loadingProgress, setLoadingProgress] = useState(0);
  const [statusText, setStatusText] = useState("");

  const hasAttemptedBoot = useRef(false);

  const fetchMetadata = useCallback(async (serverUrl) => {
    try {
      const response = await fetch(`${serverUrl}/api/game-metadata`);
      if (!response.ok) throw new Error("Metadata fetch failed");
      const data = await response.json();
      GameDataManager.initialize(data);
      return true;
    } catch (err) {
      console.error("Metadata Sync Error:", err);
      return false;
    }
  }, []);

  const bootSequence = useCallback(
    async (serverUrl, token) => {
      if (isBooting) return;

      setIsBooting(true);
      setLoadingProgress(10);
      setStatusText("Initializing Systems...");

      try {
        setStatusText("Fetching Galactic Database...");
        const success = await fetchMetadata(serverUrl);
        if (!success) throw new Error("Initial metadata load failed");

        setLoadingProgress(60);

        setStatusText("Establishing Neural Link...");
        const socketInstance = connectToServer(serverUrl, token);

        socketInstance.once("session:ready", () => {
          setLoadingProgress(100);
          setStatusText("Ready to Launch");

          setTimeout(() => {
            setIsInGame(true);
            setIsBooting(false);
          }, 600);
        });

        socketInstance.once("connect_error", (err) => {
          console.error("Socket error:", err);
          setStatusText("Neural Link Failed");
          setTimeout(() => setIsBooting(false), 2000);
        });
      } catch (err) {
        console.error("Boot error:", err);
        setStatusText("System Failure");
        setTimeout(() => setIsBooting(false), 2000);
      }
    },
    [connectToServer, isBooting, fetchMetadata],
  );

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

    const handleDataUpdate = async () => {
      console.log("🔄 [System] Datapacks changed on server. Synchronizing...");

      const savedServer = localStorage.getItem("activeServer");
      if (!savedServer) return;

      const { connectUrl } = JSON.parse(savedServer);
      const success = await fetchMetadata(connectUrl);

      if (success) {
        console.log("✅ [System] Local database updated successfully.");
      }
    };

    socket.on("system:data_updated", handleDataUpdate);

    return () => {
      socket.off("system:data_updated", handleDataUpdate);
    };
  }, [socket, isConnected, fetchMetadata]);

  useEffect(() => {
    if (user && !hasAttemptedBoot.current && !isConnected && !isInGame) {
      const savedServer = localStorage.getItem("activeServer");
      const token = user?.token;

      if (savedServer && token) {
        const server = JSON.parse(savedServer);
        hasAttemptedBoot.current = true;
        bootSequence(server.connectUrl, token);
      }
    }
  }, [user, isConnected, isInGame, bootSequence]);

  const handleStartGame = () => {
    const savedServer = localStorage.getItem("activeServer");
    const token = user?.token;

    if (savedServer && token) {
      const server = JSON.parse(savedServer);
      bootSequence(server.connectUrl, token);
    }
  };

  if (isBooting) {
    return <LoadingScreen progress={loadingProgress} statusText={statusText} />;
  }

  return (
    <div className="game-wrapper">
      {isInGame && isConnected ? (
        <GameInterface onExit={() => setIsInGame(false)} />
      ) : (
        <MainMenu onStartGame={handleStartGame} />
      )}
    </div>
  );
}

export default App;
