import * as React from "react";

import { getRemoteContextData } from "../remoteContextReloader/getRemoteContextData";

import { coreAppLogger } from "../logger";
import { AnyAction, Dispatch } from "@reduxjs/toolkit";
import { isAndroidPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";

const logger = coreAppLogger.addSubsystem("AppRemoteDataLoader");

/**
 * adds a call to the QuickBrickManager to tell the app is ready, reloads remote
 * configuration when not in dev mode, and loads basic app data in the session storage
 * @param {Object} QuickBrickManager
 * @returns {Function}
 */

type Props = {
  dispatch: Dispatch;
  testCallback: () => void;
  plugins: QuickBrickPlugin[];
  appSettings: { runtimeConfigurationUrls: { [key in string]: string } };
};

export function appRemoteDataLoader(Component: ReactComponent<any>) {
  return function AppRemoteDataLoaderRenderer(props: Props) {
    const [isDataLoaded, setIsDataLoaded] = React.useState(false);

    const loadRemoteConfigurationJSONs = async (
      dispatch: Dispatch<AnyAction>,
      state
    ) => {
      if (!__DEV__ || process.env.ENABLE_REMOTE_DATA_IN_DEV === "true") {
        logger.log({
          message: "appRemoteDataLoader: Remote data will be loaded",
          data: {
            dev: __DEV__,
            override: process.env.ENABLE_REMOTE_DATA_IN_DEV === "true",
          },
        });

        const {
          appSettings: { runtimeConfigurationUrls },
          plugins,
        } = state;

        await getRemoteContextData(dispatch, runtimeConfigurationUrls, plugins);
      } else {
        logger.log({
          message:
            "appRemoteDataLoader: Skipping remote data load, will use local json files only",
          data: {
            dev: __DEV__,
            override: process.env.ENABLE_REMOTE_DATA_IN_DEV === "true",
          },
        });
      }
    };

    const loadRemoteData = async () => {
      const { dispatch, ...state } = props;

      try {
        await loadRemoteConfigurationJSONs(dispatch, state);

        logger.debug({
          message:
            "appRemoteDataLoader: Remote data successfully finished, the app is ready to continue loading",
        });

        setIsDataLoaded(true);
      } catch (error) {
        logger.warning({
          message: `appRemoteDataLoader: A loading operation failed: ${error.message}`,
          data: { error },
        });
      }
    };

    React.useLayoutEffect(() => {
      // Resolves issue where the Android platform would not render any UI until the `quickBrickReady` event is passed.
      // To enhance app startup speed, the loading of main JSON files is now initiated before the UI rendering on Android.
      // This change allows for the app's loading processes to run in parallel with the loading of Android's native components
      // and while the splash screen is displayed, which may also play a video. This results in a smoother and quicker startup experience.
      // Remove this condition when bug will be fixed and code refactored
      if (!isAndroidPlatform()) {
        loadRemoteData();
      } else {
        setIsDataLoaded(true);
      }
    }, []);

    return isDataLoaded ? <Component {...props} /> : null;
  };
}
