import * as R from "ramda";
import { Dimensions } from "react-native";
import { loadAppContextData } from "@applicaster/zapp-react-native-redux";
import { isTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
import { mapPromises } from "@applicaster/zapp-react-native-utils/arrayUtils";
import { fetchPluginConfiguration, getPromiseForType } from "../helpers";
import { cacheAssets } from "../../AssetCache";
import { actions as appDataActions } from "@applicaster/zapp-react-native-redux/AppData";
import { logger } from "@applicaster/zapp-react-native-utils/logger";

export async function getNativeRemoteContextData(
  dispatch,
  runtimeConfigurationUrls,
  plugins
) {
  const { width, height } = Dimensions.get("window");

  const isTabletDevice = isTablet(
    { width, height },
    width > height ? "landscape" : "portrait"
  );

  const generalConfiguration = await mapPromises(getPromiseForType, [
    "remoteConfigurations",
    "pluginConfigurations",
    "pipesEndpoints",
  ]);

  loadAppContextData(dispatch, R.mergeAll([...generalConfiguration]));

  try {
    const layoutManagerPlugin = R.find(
      R.pathSatisfies(R.is(Function), ["module", "selectLayout"])
    )(plugins);

    await layoutManagerPlugin?.module?.selectLayout({
      runtimeConfigurationUrls,
      plugin: layoutManagerPlugin,
      isTablet: isTabletDevice,
    });
  } catch (error) {
    logger.error({
      message: "Error selecting layout using layout manager plugin",
      data: error,
    });
  }

  const layout = await getPromiseForType("layout");

  const apiVersion = layout?.layout?.["api_version"]; // Taken from remote configuration

  dispatch(appDataActions.merge({ layoutVersion: apiVersion || "v1" }));

  const resolvedPromises = await mapPromises(getPromiseForType, ["cellStyles"]);

  let optionalResolvedPromise;

  try {
    optionalResolvedPromise = await getPromiseForType("presetsMapping");
  } catch (e) {
    // don't break loading sequence if presetsMapping does not exist
    // only general error could be intercepted here so no way divide flow
  }

  const remoteData = R.mergeAll([
    ...resolvedPromises,
    ...generalConfiguration,
    optionalResolvedPromise,
    layout,
  ]);

  const cachedRemoteData = await cacheAssets({
    layout: remoteData.layout,
    pluginConfigurations: remoteData.pluginConfigurations,
    cellStyles: remoteData.cellStyles,
  });

  const { pluginConfigurations } = cachedRemoteData;

  const updatedPlugins = R.map(
    fetchPluginConfiguration(pluginConfigurations),
    plugins
  );

  const appProperties = R.compose(
    R.mergeLeft({
      contentTypes: remoteData.layout?.content_types,
      rivers: cachedRemoteData.layout,
      cellStyles: cachedRemoteData.cellStyles,
    }),
    R.omit(["layout"])
  )(remoteData);

  if (remoteData.presetsMapping) {
    appProperties.presetsMapping = remoteData.presetsMapping;
  }

  loadAppContextData(dispatch, {
    ...appProperties,
    plugins: updatedPlugins,
  });
}
