import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { useAtomValue } from 'jotai';
import {
  amplitudeApiKeyAtom,
  contextSourceAtom,
  dataResidencyAtom,
  envAtom,
} from 'src/atoms/envive/enviveConfig';
import { useLocalStorage } from 'src/contexts/localStorageContext';
import { orgAnalyticsGoogleAnalyticsConfigAtom } from 'src/atoms/org/orgAnalyticsConfig';
import { userIdAtom } from 'src/atoms/app';
import { useEnviveConfig } from 'src/contexts/enviveConfigContext';
import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext/featureFlagServiceContext';
import {
  AmplitudeService,
  EnviveMetricsEventName,
  SpiffyMetricsEventName,
  TrackEventParams,
} from 'src/services/amplitudeService/amplitudeService';

export { EnviveMetricsEventName, SpiffyMetricsEventName };

interface AmplitudeContextType {
  trackEvent: (params: TrackEventParams) => Promise<void>;
  isReady: boolean;
  isMockMode: boolean;
  setSupplementalDefaultProps: (props: Record<string, unknown>) => void;
}

const AmplitudeContext = createContext<AmplitudeContextType | null>(null);

export const AmplitudeProvider: React.FC<{
  externalAmplitudeService?: AmplitudeService;
  children: React.ReactNode;
}> = ({ externalAmplitudeService, children }) => {
  const userId = useAtomValue(userIdAtom);
  const amplitudeApiKey = useAtomValue(amplitudeApiKeyAtom);
  const dataResidency = useAtomValue(dataResidencyAtom);
  const orgGaConfig = useAtomValue(orgAnalyticsGoogleAnalyticsConfigAtom);
  const env = useAtomValue(envAtom);
  const contextSource = useAtomValue(contextSourceAtom);
  const { getItem } = useLocalStorage();
  const {
    featureOverrides,
    variantUrlOverride,
    variantInfoOverride,
    show,
    enviveOn,
    orgId,
    orgShortName,
    featureGates,
  } = useEnviveConfig();

  const { featureFlagService } = useFeatureFlagService();

  const [service, setService] = useState<AmplitudeService | null>(null);

  const isReady = Boolean(userId && service && service.isReady);
  const isMockMode = Boolean(service?.isMockApiKey);

  // Create service instance when dependencies are ready
  useEffect(() => {
    if (externalAmplitudeService !== undefined) {
      setService(externalAmplitudeService);
      return;
    }
    if (userId && amplitudeApiKey && dataResidency && featureFlagService) {
      const amplitudeService = new AmplitudeService({
        userId,
        amplitudeApiKey,
        dataResidency,
        env: env || '',
        contextSource: contextSource || '',
        orgShortName: orgShortName || '',
        orgId: orgId || '',
        featureFlagService,
        orgGaConfig,
        show: show ?? false,
        enviveOn: enviveOn ?? false,
        getLocalStorageItem: getItem,
      });
      setService(amplitudeService);
    } else {
      setService(null);
    }
  }, [
    userId,
    amplitudeApiKey,
    dataResidency,
    env,
    contextSource,
    orgShortName,
    featureFlagService,
    orgGaConfig,
    featureOverrides,
    variantUrlOverride,
    variantInfoOverride,
    show,
    enviveOn,
    featureGates,
    getItem,
    externalAmplitudeService,
    orgId,
  ]);

  const value = useMemo(
    () => ({
      trackEvent: async (params: TrackEventParams): Promise<void> => {
        if (service) {
          await service.trackEvent(params);
        }
      },
      isReady,
      isMockMode,
      setSupplementalDefaultProps: (props: Record<string, unknown>) => {
        if (service) {
          service.setSupplementalDefaultProps(props);
        }
      },
    }),
    [service, isReady, isMockMode],
  );

  if (!isReady && !isMockMode) {
    return null;
  }

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

export const useAmplitude = () => {
  const context = useContext(AmplitudeContext);
  if (!context) {
    throw new Error('useAmplitude must be used within AmplitudeProvider');
  }
  return context;
};
