import { ReactNode, createContext, useCallback, useContext, useMemo, useState } from 'react';
import Logger from 'src/application/logging/logger';
import { useNewOrgConfig } from 'src/hooks/NewOrgConfig';
import { WidgetConfigV3, WidgetTypeV3 } from '../typesV3';

const logger = new Logger('widgetConfigContext');

interface WidgetConfigRequest {
  widgetType: WidgetTypeV3;
  widgetConfigId: string;
}

interface WidgetConfigContextType {
  getWidgetConfig: (request: WidgetConfigRequest) => Promise<WidgetConfigV3>;
  isLoading: boolean;
}

const WidgetConfigContext = createContext<WidgetConfigContextType | undefined>(undefined);

export const WidgetConfigProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const { frontendConfig, loading: isFrontendConfigLoading } = useNewOrgConfig();
  const [isLoadingWidgetConfig, setIsLoadingWidgetConfig] = useState(false);

  const getWidgetConfig = useCallback(
    async (request: WidgetConfigRequest): Promise<WidgetConfigV3> => {
      setIsLoadingWidgetConfig(true);
      logger.logDebug('retrieving widget config', {
        widgetConfigId: request.widgetConfigId,
        widgetType: request.widgetType,
      });
      if (isFrontendConfigLoading) {
        setIsLoadingWidgetConfig(false);
        throw new Error('Frontend config is loading');
      }

      const { widgetConfigId, widgetType } = request;
      const response = frontendConfig?.widgetConfigs?.[widgetConfigId];
      logger.logDebug('returning widget config response', response);

      if (widgetConfigId === 'fake-widget-config-id') {
        return {} as WidgetConfigV3;
      }

      if (
        [
          WidgetTypeV3.SocialProofV3,
          WidgetTypeV3.ChatPreviewV3,
          WidgetTypeV3.ChatPreviewComparisonV3,
          WidgetTypeV3.ChatPreviewLoadingV3,
        ].includes(widgetType)
      ) {
        if (response?.type !== WidgetTypeV3.SocialProofV3) {
          setIsLoadingWidgetConfig(false);
          throw new Error(
            `Widget type: ${widgetType} does not match widget config type: ${response?.type}`,
          );
        }
      } else if (response?.type !== widgetType) {
        setIsLoadingWidgetConfig(false);
        throw new Error(
          `Widget type: ${widgetType} does not match widget config type: ${response?.type}`,
        );
      }

      if (!response) {
        setIsLoadingWidgetConfig(false);
        throw new Error(
          `No widget config response found for widget type: ${request.widgetType} and widget config id: ${request.widgetConfigId}`,
        );
      }
      setIsLoadingWidgetConfig(false);
      return response;
    },
    [frontendConfig, isFrontendConfigLoading],
  );

  const isLoading = isFrontendConfigLoading || isLoadingWidgetConfig;

  const value = useMemo(() => ({ getWidgetConfig, isLoading }), [getWidgetConfig, isLoading]);

  return <WidgetConfigContext.Provider value={value}>{children}</WidgetConfigContext.Provider>;
};

export const useWidgetConfig = () => {
  const context = useContext(WidgetConfigContext);
  if (!context) {
    throw new Error('useWidgetConfig must be used within a WidgetConfigProvider');
  }
  return context;
};
