import React, { ComponentClass, FC, useEffect } from "react";
import * as R from "ramda";
import { DispatchProp } from "react-redux";

import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";

import {
  mapAndSplit,
  mapPromises,
  reducePromises,
} from "@applicaster/zapp-react-native-utils/arrayUtils";

import {
  DATASOURCE_CHUNKS,
  getDatasourceUrl,
  ignoreComponentsWithClearCacheFlag,
  usePipesContexts,
} from "./utils";
import { useLoadPipesDataDispatch } from "@applicaster/zapp-react-native-utils/reactHooks";

type RiverProps = {
  dispatch: DispatchProp;
  river: ZappRiver;
};

type ZappComponent = FC<any> | ComponentClass<any>;

export function WithRiverFeedLoader(Component: ZappComponent) {
  return function WrappedWithRiverFeedLoader(props: RiverProps) {
    const { river } = props;
    const { screenData, pathname } = useRoute();
    const pipesContexts = usePipesContexts(river.id, pathname);

    const loadPipesDataDispatcher = useLoadPipesDataDispatch();

    const componentsToLoad = ignoreComponentsWithClearCacheFlag(
      river?.ui_components || []
    );

    useEffect(() => {
      const dataSources = R.compose(
        R.map(R.reject(R.isEmpty)),
        mapAndSplit(
          getDatasourceUrl({
            screenData,
            ...pipesContexts,
          }),
          DATASOURCE_CHUNKS
        )
      )(componentsToLoad);

      // TODO Refactor with Ramda
      const nonEmptyDataSources = dataSources.map((item) =>
        item?.filter((item2) => item2 !== undefined)
      );

      reducePromises<string, void>(
        mapPromises<string, void>((url) =>
          loadPipesDataDispatcher(
            url,
            {},
            {
              withResolvers: true,
              withScreenRouteMapping: true,
            }
          )
        ),
        undefined,
        nonEmptyDataSources
      );
    }, []);

    return <Component {...props} />;
  };
}
