import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';
import { PusherClient, type ConnectionState } from './pusher-client';
import { useSessionStore } from '@/stores/session-store';
import { appConfig } from '@/config/env';

const PusherContext = createContext<PusherClient | null>(null);
const PusherStateContext = createContext<ConnectionState>('disconnected');

export function PusherProvider({ children }: { children: ReactNode }) {
  const token = useSessionStore((s) => s.token);
  const [connectionState, setConnectionState] =
    useState<ConnectionState>('disconnected');

  const client = useMemo(() => {
    if (!token) {
      return null;
    }

    return new PusherClient({
      url: appConfig.pusherUrl,
      getToken: () => useSessionStore.getState().token,
    });
  }, [token]);

  useEffect(() => {
    if (!client) {
      return;
    }

    const unsubscribeState = client.onStateChange((state) => {
      setConnectionState(state);
    });

    client.connect();

    return () => {
      unsubscribeState();
      client.disconnect();
      setConnectionState('disconnected');
    };
  }, [client]);

  return (
    <PusherContext.Provider value={client}>
      <PusherStateContext.Provider value={connectionState}>
        {children}
      </PusherStateContext.Provider>
    </PusherContext.Provider>
  );
}

/**
 * Returns the PusherClient instance, or null if not connected.
 */
export function usePusherClient(): PusherClient | null {
  return useContext(PusherContext);
}

/**
 * Returns the current WebSocket connection state.
 */
export function usePusherConnectionState(): ConnectionState {
  return useContext(PusherStateContext);
}
