"use client";
import { Power, PowerOff } from "@mui/icons-material";
import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
  useCallback,
} from "react";
import { toast } from "react-toastify";
import { io } from "socket.io-client";
import { useAuth } from "./auth";

const SocketContext = createContext({
  socket: null,
  status: "",
});

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

export const SocketProvider = ({ children }) => {
  const { user } = useAuth();
  const socketToastId = useRef(null);
  const [status, setStatus] = useState("");
  const [clientsOnline, setClientsOnline] = useState([]);

  const socket = useMemo(() => {
    return io(`${process.env.NEXT_PUBLIC_SERVER_SOCKET_URL}`, {
      path: "/notification/socket.io",
      autoConnect: false,
      auth: { token: null },
    });
  }, []);

  useEffect(() => {
    if (user?.telephone_id) {
      socket.auth.token = { telephone_id: user.telephone_id, user_id: user.id };
    }
  }, [user, socket]);

  const handleConnect = useCallback(() => setStatus("connected"), []);
  const handleDisconnect = useCallback(() => setStatus("disconnected"), []);
  const handleConnectError = useCallback(() => setStatus("error"), []);

  useEffect(() => {
    socket.on("connect", handleConnect);
    socket.on("disconnect", handleDisconnect);
    socket.on("connect_error", handleConnectError);

    return () => {
      socket.off("connect", handleConnect);
      socket.off("disconnect", handleDisconnect);
      socket.off("connect_error", handleConnectError);
    };
  }, [socket, handleConnect, handleDisconnect, handleConnectError]);

  useEffect(() => {
    if (status === "connected") {
      toast.update(socketToastId.current, {
        containerId: "socket_connection",
        type: "success",
        render: "ارتباط با سرور برقرار شد",
        autoClose: 2000,
        closeButton: true,
        closeOnClick: true,
        icon: ({ theme, type }) => <Power />,
      });
    } else if (status === "error" || status === "disconnected") {
      if (socketToastId.current) {
        toast.update(socketToastId.current, {
          containerId: "socket_connection",
          type: "warning",
          render: "ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…",
          autoClose: false,
          closeButton: false,
          draggable: false,
          icon: ({ theme, type }) => <PowerOff />,
        });
      } else {
        socketToastId.current = toast.warn(
          "ارتباط با سرور قطع شد. در حال تلاش برای بازیابی…",
          {
            containerId: "socket_connection",
            autoClose: false,
            closeButton: false,
            draggable: false,
            icon: ({ theme, type }) => <PowerOff />,
          },
        );
      }
    }
  }, [status]);

  useEffect(() => {
    if (status == "connected") return;

    socket.connect();

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

  useEffect(() => {
    const handleNotification = (data) => {
      setClientsOnline(data.clients);
    };
    socket.on("onlineClientsUpdated", handleNotification);

    return () => {
      socket.off("onlineClientsUpdated", handleNotification);
    };
  }, [socket]);

  const contextValue = useMemo(
    () => ({ socket, status, clientsOnline }),
    [socket, status, clientsOnline],
  );

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

export default SocketContext;
