import React, { useState } from 'react';
import {
  AppState,
  LogBox,
  type Permission,
  PermissionsAndroid,
  Platform,
  StatusBar,
} from 'react-native';
import { Provider } from 'react-redux';
import { init as initApm } from '@cobo/apm-rum-react-native';
import { PersistGate } from 'redux-persist/integration/react';
import { NavigationContainer } from '@react-navigation/native';
import * as Sentry from '@sentry/react-native';
import codePush from 'react-native-code-push';
import AsyncStorage from '@react-native-async-storage/async-storage';
import CodePush from 'react-native-code-push';
import store, { persistor } from './src/store/store';

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

import { APM_APP_NAME, APM_BASE_URL, ENV } from './src/constants/config';
import { COLORS } from './RN-UI-LIB/src/styles/colors';
import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from './src/common/Constants';
import Permissions from './src/screens/permissions/Permissions';
import { setJsErrorHandler } from './src/services/exception-handler.service';
import SuspenseLoader from './RN-UI-LIB/src/components/suspense_loader/SuspenseLoader';
import ErrorBoundary from './src/common/ErrorBoundary';
import { type TDocumentObj } from './src/screens/caseDetails/interface';
import AuthRouter from './src/screens/auth/AuthRouter';
import { initSentry } from './src/components/utlis/sentry';
import {
  getPermissionsToRequest,
  getPermissionsToValidate,
} from './src/components/utlis/PermissionUtils';
import usePolling from './src/hooks/usePolling';
import { MILLISECONDS_IN_A_SECOND } from './RN-UI-LIB/src/utlis/common';
import { setItem } from './src/components/utlis/storageHelper';
import { StorageKeys } from './src/types/storageKeys';
import dayJs from 'dayjs';
import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage';
import analytics from '@react-native-firebase/analytics';
import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service';
import { addClickstreamEvent } from './src/services/clickstreamEventService';

initSentry();

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

setJsErrorHandler();
LogBox.ignoreAllLogs();

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

async function checkCodePushAndSync() {
  try {
    await CodePush.sync({
      installMode: codePush.InstallMode.IMMEDIATE,
    });
  } catch (error) {}
}

function handleAppStateChange(nextAppState: any) {
  if (nextAppState == 'active') {
    checkCodePushAndSync();
  }
}

const PERMISSION_CHECK_POLL_INTERVAL = 5 * MILLISECONDS_IN_A_SECOND;

function App() {
  const [permissions, setPermissions] = React.useState(true);
  const [isGlobalDocumentMapLoaded, setIsGlobalDocumentMapLoaded] = React.useState(false);
  const [routeName, setRouteName] = useState('Unknown');

  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 });
  }

  usePolling(askForPermissions, PERMISSION_CHECK_POLL_INTERVAL);

  initApm({
    serviceName: APM_APP_NAME,
    serverUrl: APM_BASE_URL,
    serviceVersion: '1.0.0',
    environment: ENV,
    active: true,
  });

  React.useEffect(() => {
    askForPermissions();
    const appStateChange = AppState.addEventListener('change', async (change) => {
      handleAppStateChange(change);
      hydrateGlobalImageMap();
    });
    (async () => {
      const data = await AsyncStorage.getItem(LocalStorageKeys.GLOBAL_DOCUMENT_MAP);
      if (data) {
        const parsedData = JSON.parse(data);
        GlobalDocumentMap = parsedData;
      }
      setIsGlobalDocumentMapLoaded(true);
    })();
    checkCodePushAndSync();
    handleUpdatedConfigureValuesFromFirebase();
    setForegroundTimeStampAndClickstream();

    return () => {
      appStateChange.remove();
    };
  }, []);

  return (
    <Provider store={store}>
      <PersistGate
        loading={<FullScreenLoader loading isTranslucent={false} />}
        persistor={persistor}
      >
        <NavigationContainer
          ref={navigationRef}
          onStateChange={async (state) => {
            const currentRouteName = getActiveRouteName(state);
            if (routeName !== currentRouteName) {
              await analytics().logScreenView({
                screen_name: currentRouteName,
                screen_class: currentRouteName,
              });

              await analytics().logEvent('screen_view', {
                screen_name: currentRouteName,
                screen_class: currentRouteName,
              });

              setRouteName(currentRouteName);
            }
          }}
        >
          <StatusBar backgroundColor={COLORS.BACKGROUND.INDIGO_DARK} />
          <SuspenseLoader
            fallBack={<FullScreenLoader loading isTranslucent={false} />}
            loading={!isGlobalDocumentMapLoaded}
            children={
              <ErrorBoundary>{permissions ? <AuthRouter /> : <Permissions />}</ErrorBoundary>
            }
          />
        </NavigationContainer>
        <ToastContainer config={toastConfigs} position="top" topOffset={18} />
      </PersistGate>
    </Provider>
  );
}

const AppWithSentry = Sentry.wrap(App);

export default AppWithSentry;
