// contexts/SocketContext.tsx
import React, {
  createContext,
  useContext,
  useEffect,
  useState,
  ReactNode,
} from "react";
import SocketService from "../services/paymentSocket";

interface SocketContextType {
  isConnected: boolean;
  registerTransaction: (
    transactionId: string | null | undefined
  ) => Promise<void>;
  onPaymentConfirmation: (callback: (data: any) => void) => void;
  offPaymentConfirmation: () => void;
  disconnect: () => void;
  connectSocket: () => void;
}

const SocketContext = createContext<SocketContextType | undefined>(undefined);

interface SocketProviderProps {
  children: ReactNode;
}

export const SocketProvider: React.FC<SocketProviderProps> = ({ children }) => {
  const [isConnected, setIsConnected] = useState(false);

  const connectSocket = async () => {
    try {
      await SocketService.connect();
      setIsConnected(true);
    } catch (error) {
      console.error("Failed to connect socket:", error);
      setIsConnected(false);
      throw error;
    }
  };

  const registerTransaction = async (
    transactionId: string | null | undefined
  ) => {
    try {
      if (!transactionId) {
        throw new Error("Transaction Id missing in register transaction");
      }
      if (!isConnected) {
        await connectSocket();
      }
      await SocketService.registerTransaction(transactionId);
    } catch (err) {
      throw err;
    }
  };

  const onPaymentConfirmation = (callback: (data: any) => void) => {
    SocketService.onPaymentConfirmation(callback);
  };

  const offPaymentConfirmation = () => {
    SocketService.offPaymentConfirmation();
  };

  return (
    <SocketContext.Provider
      value={{
        isConnected,
        registerTransaction,
        onPaymentConfirmation,
        offPaymentConfirmation,
        disconnect: () => {
          SocketService.disconnect();
          setIsConnected(false);
        },
        connectSocket,
      }}
    >
      {children}
    </SocketContext.Provider>
  );
};

export const useSocket = (): SocketContextType => {
  const context = useContext(SocketContext);
  if (context === undefined) {
    throw new Error("useSocket must be used within a SocketProvider");
  }
  return context;
};
