import AsyncStorage from '@react-native-async-storage/async-storage';
import { NavigationContainer } from '@react-navigation/native';
import React, { useEffect } from 'react';
import {
  AppState,
  LogBox,
  PermissionsAndroid,
  Platform,
  StatusBar,
  type Permission,
} from 'react-native';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import store, { persistor } from './src/store/store';

import { navigationRef } from '@utils/navigationUtlis';
import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader';
import { toastConfigs, ToastContainer } from './RN-UI-LIB/src/components/toast';

import { hydrateGlobalImageMap } from '@common/CachedImage';
import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from '@common/Constants';
import { getAppVersion, sendDeviceDetailsToClickstream } from '@components/utlis/commonFunctions';
import { linkingConf } from '@components/utlis/deeplinkingUtils';
import { getBuildFlavour, restartApp } from '@components/utlis/DeviceUtils';
import { initSentry } from '@components/utlis/sentry';
import { GLOBAL, setGlobalBuildFlavour } from '@constants/Global';
import { AppStates } from '@interfaces/appStates';
import analytics from '@react-native-firebase/analytics';
import { COLORS } from '@rn-ui-lib/colors';
import { type TDocumentObj } from '@screens/caseDetails/interface';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import { setJsErrorHandler } from '@services/exception-handler.service';
import syncSelfCallData from '@services/syncSelfCallData';
import { getPermissionsToRequest } from '@utils/PermissionUtils';
import dayJs from 'dayjs';
import CodePushLoadingModal, { CodePushLoadingModalRef } from './CodePushModal';
import ErrorBoundary from './src/common/ErrorBoundary';
import ScreenshotBlocker from './src/components/utlis/ScreenshotBlocker';
import { setItem } from './src/components/utlis/storageHelper';
import { BASE_AV_APP_URL, ENV } from './src/constants/config';
import AuthRouter from './src/screens/auth/AuthRouter';
import Permissions from './src/screens/permissions/Permissions';
import fetchUpdatedRemoteConfig from './src/services/firebaseFetchAndUpdate.service';
import { StorageKeys } from './src/types/storageKeys';
import { CodePushStorageKeys, useCheckVersion } from '@hooks/useCheckVersion';

if (!__DEV__) {
  initSentry();
}

if (ENV !== 'prod') {
  // mockApiServer();
}

setJsErrorHandler();
LogBox.ignoreAllLogs();

export let GlobalDocumentMap: Record<string, TDocumentObj | string> = {};

function App() {
  const [permissions, setPermissions] = React.useState(true);
  const modalRef = React.useRef<CodePushLoadingModalRef>(null);

  const { checkForUpdates, applyUpdate } = useCheckVersion({
    apiConfig: {
      baseUrl: BASE_AV_APP_URL,
      appVersionParam: getAppVersion(),
    },
    onUpdateAvailable: async (result) => {
      const updateCheck = (await AsyncStorage.getItem(CodePushStorageKeys.CodePushVersionTag)) ?? 0;
      if (+result.versionTag === +updateCheck) {
        addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_INFINITE_INSTALL_ERROR, {});
        return;
      }

      if (result.isAvailable) {
        addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_INSTALLING_CODEPUSH, {});
        modalRef.current?.show();
        applyUpdate(result.url, result.versionTag);
      }
    },
    onDownloadProgress: (received, total) => {
      modalRef.current?.updateProgress({
        totalBytes: +total,
        receivedBytes: +received,
      });
    },
    onUpdateSuccess: () => {
      setTimeout(() => {
        restartApp();
      }, 4000);
    },
    onUpdateFail: (message?: string) => {
      addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_CODEPUSH_UNKNOWN_ERROR, { message });
      modalRef.current?.hide();
    },
  });

  const askForPermissions = async () => {
    const permissionsToRequest = await getPermissionsToRequest();

    if (Platform.OS === 'android') {
      PermissionsAndroid.requestMultiple(permissionsToRequest)
        .then(async (result) => {
          let isAllPermissionsGranted = true;
          for (const permission in result) {
            if (result?.[permission as Permission] !== PermissionsAndroid.RESULTS.GRANTED) {
              isAllPermissionsGranted = false;
              break;
            }
          }
          setPermissions(isAllPermissionsGranted);
        })
        .catch((err) => {
          setPermissions(false);
        });
    }
  };

  const getActiveRouteName = (state) => {
    if (!state || typeof state.index !== 'number') {
      return 'Unknown';
    }
    const route = state.routes[state.index];
    if (route.state) {
      return getActiveRouteName(route.state);
    }
    return route?.name || '';
  };

  async function setForegroundTimeStampAndClickstream() {
    const now = dayJs().toString();
    await setItem(StorageKeys.APP_FOREGROUND_TIMESTAMP, now);
    addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }, true);
  }

  useEffect(() => {
    ScreenshotBlocker.unblockScreenshots();
    getBuildFlavour().then((flavour) => {
      setGlobalBuildFlavour(flavour);
    });
    // Device Details
    sendDeviceDetailsToClickstream();
  }, []);

  React.useEffect(() => {
    fetchUpdatedRemoteConfig();
    askForPermissions();
    const appStateChange = AppState.addEventListener('change', async (change) => {
      if (change === AppStates.ACTIVE) {
        askForPermissions();
        if (GLOBAL.AGENT_ID) {
          syncSelfCallData(GLOBAL.AGENT_ID);
        }
        checkForUpdates();
      }
      hydrateGlobalImageMap();
    });
    (async () => {
      const data = await AsyncStorage.getItem(LocalStorageKeys.GLOBAL_DOCUMENT_MAP);
      if (data) {
        const parsedData = JSON.parse(data);
        GlobalDocumentMap = parsedData;
      }
    })();
    setForegroundTimeStampAndClickstream();

    return () => {
      appStateChange.remove();
    };
  }, []);
  return (
    <Provider store={store}>
      <PersistGate
        loading={<FullScreenLoader loading isTranslucent={false} />}
        persistor={persistor}
      >
        <NavigationContainer
          linking={linkingConf}
          ref={navigationRef}
          onStateChange={async (state) => {
            const currentRouteName = getActiveRouteName(state);
            await analytics().logScreenView({
              screen_name: currentRouteName,
              screen_class: currentRouteName,
            });
          }}
        >
          <StatusBar backgroundColor={COLORS.BACKGROUND.INDIGO_DARK} />
          <ErrorBoundary>{permissions ? <AuthRouter /> : <Permissions />}</ErrorBoundary>
        </NavigationContainer>
        <ToastContainer config={toastConfigs} position="top" topOffset={18} />
        <CodePushLoadingModal ref={modalRef} />
      </PersistGate>
    </Provider>
  );
}

export default App;
