"use client";

import React, { createContext, useContext, useEffect, useState, ReactNode } from "react";
import { io, Socket } from "socket.io-client";
import { useAppSelector } from "@/store/hooks";

interface SocketContextProps {
  socket: Socket | null;
  onlineUsers: string[];
}

const SocketContext = createContext<SocketContextProps>({
  socket: null,
  onlineUsers: [],
});

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

export const SocketProvider = ({ children }: { children: ReactNode }) => {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [onlineUsers, setOnlineUsers] = useState<string[]>([]);

  const user = useAppSelector((state) => state.auth.user);

  useEffect(() => {
    const token = localStorage.getItem("token") || sessionStorage.getItem("token");
    if (!token || !user) return;

    // Use window.location.hostname and standard port for API or hardcoded for now
    const socketUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000";

    const newSocket = io(socketUrl, {
      auth: { token },
      transports: ["polling"],
    });

    newSocket.on("connect", () => {
      console.log("Connected to socket server");
    });

    newSocket.on("initial_online_users", (userIds: string[]) => {
      console.log("[Socket] initial_online_users received:", userIds);
      setOnlineUsers(userIds);
    });

    newSocket.on("user_status", (data: { userId: string; status: string }) => {
      console.log("[Socket] user_status received:", data);
      setOnlineUsers((prev) => {
        if (data.status === "online") {
          return prev.includes(data.userId) ? prev : [...prev, data.userId];
        } else {
          return prev.filter((id) => id !== data.userId);
        }
      });
    });

    // The backend no longer emits online-users to avoid overwriting state on multi-tab disconnects

    setSocket(newSocket);

    return () => {
      newSocket.disconnect();
    };
  }, [user]);

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