import { useEffect, useRef } from 'react';
import { ChatElementDisplayLocationV3 } from 'src/application/models/chatElementDisplayLocationV3';
import Logger from 'src/application/logging/logger';
import { useEnviveConfig } from 'src/contexts/enviveConfigContext';
import { useSalesAgent } from 'src/contexts/salesAgentContext/salesAgentContext';
import { useChatToggle } from 'src/hooks/ChatToggle';

const logger = new Logger('WindowChatToggleBinder');

const attachedPrefixes = new Set<string>();

export const WindowChatToggleBinder = () => {
  const triggerLocation = ChatElementDisplayLocationV3.WINDOW_API_CALL;
  const hook = useChatToggle();
  const { onTypedMessageSubmitted } = useSalesAgent();
  const { identifyingPrefix } = useEnviveConfig();

  const openChatRef = useRef<(triggerId?: string) => void>(() => {});
  const closeChatRef = useRef<(triggerId?: string) => void>(() => {});
  const toggleChatRef = useRef<(triggerId?: string) => void>(() => {});
  const isOpenRef = useRef<boolean>(hook.isOpen);
  const openChatWithPromptRef = useRef<(prompt: string, triggerId?: string) => void>(() => {});

  useEffect(() => {
    openChatRef.current = (triggerId?: string) => hook.openChat(triggerLocation, triggerId);
    closeChatRef.current = (triggerId?: string) => hook.closeChat(triggerLocation, triggerId);
    toggleChatRef.current = (triggerId?: string) => hook.toggle(triggerLocation, triggerId);
    isOpenRef.current = hook.isOpen;
    openChatWithPromptRef.current = (prompt: string, triggerId?: string) => {
      onTypedMessageSubmitted({
        query: prompt,
        userTyped: false,
        displayLocation: ChatElementDisplayLocationV3.WINDOW_API_CALL,
      });
      hook.openChat(triggerLocation, triggerId);
    };
  }, [hook, onTypedMessageSubmitted, triggerLocation]);

  useEffect(() => {
    if (!identifyingPrefix || attachedPrefixes.has(identifyingPrefix)) return;
    try {
      const win = window as unknown as Window & Record<string, unknown>;
      if (!win[identifyingPrefix]) {
        win[identifyingPrefix] = {} as Record<string, unknown>;
      }
      const api = win[identifyingPrefix] as Record<string, unknown>;
      api.openChat = (triggerId?: string) => openChatRef.current?.(triggerId);
      api.closeChat = (triggerId?: string) => closeChatRef.current?.(triggerId);
      api.toggleChat = (triggerId?: string) => toggleChatRef.current?.(triggerId);
      api.getChatIsOpen = () => !!isOpenRef.current;
      api.openChatWithPrompt = (prompt: string, triggerId?: string) =>
        openChatWithPromptRef.current?.(prompt, triggerId);

      attachedPrefixes.add(identifyingPrefix);

      // Always expose the same API at window["spiffy"] so both work (e.g. injection-bundle + spiffy)
      const spiffyAlias = 'spiffy';
      if (!attachedPrefixes.has(spiffyAlias)) {
        win[spiffyAlias] = api;
        attachedPrefixes.add(spiffyAlias);
      }

      logger.logDebug(
        `Chat toggle attached at window["${identifyingPrefix}"] and window["${spiffyAlias}"]`,
      );
    } catch (e) {
      logger.logError('Failed to attach Chat toggle functions', e);
    }
  }, [identifyingPrefix]);

  return null;
};
