import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { io, Socket } from "socket.io-client";

export interface SocketContextType {
  socket: Socket | null;
  subscribeNotifications: (
    userId: string,
    callback: (data: any) => void,
  ) => void;
  unsubscribeNotifications: (userId: string) => void;
}

export const SocketContext = createContext<SocketContextType>({
  socket: null,
  subscribeNotifications: () => {},
  unsubscribeNotifications: () => {},
});

export const useSocketContext = () => useContext(SocketContext);

export default function SocketProvider({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const [socket, setSocket] = useState<Socket | null>(null);
  const socketUrl = process.env.NEXT_PUBLIC_SOCKET_URL;

  useEffect(() => {
    const newSocket = io(socketUrl as string, {
      withCredentials: true,
      transports: ["websocket"],
    });

    newSocket.on("connect", () => {
      setSocket(newSocket);
      console.log("🔌 Socket connected:", newSocket.connected); // Should be true
    });

    newSocket.on("connect_error", (err) => {
      console.error("❌ Socket connection error:", err.message);
    });

    newSocket.on("disconnect", (reason) => {
      console.warn("⚠️ Socket disconnected:", reason);
    });

    return () => {
      newSocket.close(); // Clean up on unmount
    };
  }, []);

  const subscribeNotifications = useCallback(
    (userId: string, callback: (data: any) => void) => {
      if (socket) {
        console.log("🚀 ~ SocketProvider ~ socket:", socket);
        const eventName = `ealmuk-notification:${userId}`;
        socket.on(eventName, callback);
      }
    },
    [socket],
  );

  const unsubscribeNotifications = useCallback(
    (userId: string) => {
      if (socket) {
        const eventName = `ealmuk-notification:${userId}`;
        socket.off(eventName);
      }
    },
    [socket],
  );

  const contextValue = useMemo(
    () => ({
      socket,
      subscribeNotifications,
      unsubscribeNotifications,
    }),
    [socket, subscribeNotifications, unsubscribeNotifications],
  );

  return (
    <SocketContext.Provider value={contextValue}>
      {children}
    </SocketContext.Provider>
  );
}
