import React, {
  createContext,
  useState,
  useCallback,
  useRef,
  useEffect,
} from "react";
import { io } from "socket.io-client";
import PlayerManager from "../services/PlayerManager"; // Імпортуємо менеджер

export const SocketContext = createContext(null);

export const SocketProvider = ({ children }) => {
  const [socket, setSocket] = useState(null);
  const [isConnected, setIsConnected] = useState(false);

  const socketRef = useRef(null);

  const connectToServer = useCallback((url, token) => {
    if (socketRef.current?.connected) {
      return socketRef.current;
    }

    const userInfo = JSON.parse(localStorage.getItem("user"));
    const newSocket = io(url.replace("/game-api", ""), {
      path: "/socket.io/",
      auth: { token, username: userInfo?.username },
      transports: ["websocket"],
      reconnectionAttempts: 5,
    });

    newSocket.on("connect", () => {
      console.log("✅ Connected with ID:", newSocket.id);
      setIsConnected(true);
    });

    newSocket.on("session:ready", (data) => {
      PlayerManager.setInitialState(data.onlinePlayers, data.offlinePlayers);
    });

    newSocket.on("player:joined", (data) => {
      PlayerManager.handlePlayerJoined(data.username);
    });

    newSocket.on("player:left", (data) => {
      PlayerManager.handlePlayerLeft(data.username);
    });

    newSocket.on("disconnect", (reason) => {
      setIsConnected(false);
    });

    newSocket.on("connect_error", (err) => {
      console.error("⚠️ Connection error:", err.message);
    });

    socketRef.current = newSocket;
    setSocket(newSocket);

    return newSocket;
  }, []);

  const disconnectFromServer = useCallback(() => {
    if (socketRef.current) {
      socketRef.current.disconnect();
      socketRef.current = null;
      setSocket(null);
      setIsConnected(false);
    }
  }, []);

  useEffect(() => {
    return () => {
      if (socketRef.current) socketRef.current.disconnect();
    };
  }, []);

  return (
    <SocketContext.Provider
      value={{ socket, isConnected, connectToServer, disconnectFromServer }}
    >
      {children}
    </SocketContext.Provider>
  );
};
