import {
  createContext,
  useContext,
  useEffect,
  useState,
  useCallback,
} from 'react';
import Zendesk, { ZendeskAPI } from 'react-zendesk';

import { isProd } from 'src/constants';
import useAuth from 'src/contexts/JWTContext';
import { getZendeskJWT } from 'src/services/zendeskService';

const ZENDESK_KEY = import.meta.env.VITE_ZENDESK_KEY;
export const CUSTOM_ZENDESK_Z_INDEX = 9786543;

type ZendeskContextType = {
  onShow: () => void;
  onHide: () => void;
  onSetLocale: (language: string) => void;
  isWidgetOpen: boolean;
  showSupportButton: boolean;
  setShowSupportButton: (show: boolean) => void;
  totalUnreadMessagesCount: number;
};

const ZendeskContext = createContext<ZendeskContextType | null>(null);

export const ZendeskProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const { user } = useAuth();
  const [isWidgetOpen, setIsWidgetOpen] = useState(false);
  const [showSupportButton, setShowSupportButton] = useState(true);
  const [zendeskConfigLoaded, setZendeskConfigLoaded] = useState(false);
  const [totalUnreadMessagesCount, setTotalUnreadMessagesCount] = useState(0);

  useEffect(() => {
    if (!user || !zendeskConfigLoaded) return;

    ZendeskAPI(
      'messenger',
      'loginUser',
      function jwtCallback(callback: any) {
        getZendeskJWT()
          .then(response => {
            callback(response.data.token);
          })
          .catch(() => {
            callback(null);
          });
      },
      function loginCallback(error: any) {
        if (error) {
          setShowSupportButton(false);
        } else {
          ZendeskAPI('messenger:set', 'locale', user.language);
        }
      },
    );
  }, [user?.id, zendeskConfigLoaded]);

  useEffect(() => {
    if (!zendeskConfigLoaded || user) return;

    ZendeskAPI('messenger', 'resetWidget', () => {
      ZendeskAPI('messenger', 'logoutUser');
      ZendeskAPI('messenger', 'close');
    });
  }, [zendeskConfigLoaded, user]);

  useEffect(() => {
    if (!zendeskConfigLoaded) return;

    const handleOpen = () => {
      setIsWidgetOpen(true);

      ZendeskAPI('messenger', 'loginUser', function jwtCallback(callback: any) {
        getZendeskJWT()
          .then(response => {
            callback(response.data.token);
          })
          .catch(() => {
            callback(null);
          });
      });
    };
    const handleClose = () => setIsWidgetOpen(false);
    const handleUnreadMessages = (count: number) => {
      if (count > 0) {
        setShowSupportButton(true);
      }
      setTotalUnreadMessagesCount(count);
    };

    ZendeskAPI('messenger:on', 'open', handleOpen);
    ZendeskAPI('messenger:on', 'close', handleClose);
    ZendeskAPI('messenger:on', 'unreadMessages', handleUnreadMessages);

    //Setted by API to handle and select the zendesk messenger iframe
    ZendeskAPI('messenger:set', 'zIndex', CUSTOM_ZENDESK_Z_INDEX);
  }, [zendeskConfigLoaded]);

  const onShow = useCallback(() => {
    if (!user) return;
    ZendeskAPI('messenger', 'open');
  }, [user]);

  const onHide = useCallback(() => {
    if (!user) return;
    ZendeskAPI('messenger', 'close');
    setIsWidgetOpen(false);
  }, [user]);

  const onSetLocale = useCallback(
    (language: string) => {
      ZendeskAPI('messenger:set', 'locale', language);
    },
    [user],
  );

  return (
    <ZendeskContext.Provider
      value={{
        onShow,
        onHide,
        onSetLocale,
        isWidgetOpen,
        showSupportButton,
        setShowSupportButton,
        totalUnreadMessagesCount,
      }}
    >
      {isProd && (
        <Zendesk
          defer
          zendeskKey={ZENDESK_KEY}
          onLoaded={() => setZendeskConfigLoaded(true)}
        />
      )}
      {children}
    </ZendeskContext.Provider>
  );
};

export const useZendesk = () => {
  const context = useContext(ZendeskContext);
  if (!context) {
    throw new Error('useZendesk must be used within a ZendeskProvider');
  }
  return context;
};
