/// <reference types="@applicaster/applicaster-types" />

import * as React from "react";
import * as R from "ramda";
import { handleActionSchemeUrl } from "@applicaster/quick-brick-core/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/useUrlSchemeHandler";
import { CellTapContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellTapContext";
import {
  useNavigation,
  useProfilerLogging,
  useRoute,
} from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import { ZappPipesEntryContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
import { toBooleanWithDefaultTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
import { ActionExecutorContext } from "@applicaster/zapp-react-native-utils/actionsExecutor/ActionExecutorContext";

import { isFunction, noop } from "../../functionUtils";
import { useSendAnalyticsOnPress } from "../analytics";
import { logOnPress, warnEmptyContentType } from "./helpers";

/**
 * If onCellTap is defined execute the function and
 * skip default logic.
 * @return void
 */

type Props = {
  item?: ZappEntry;
  index?: number;
  component?: ZappUIComponent;
  zappPipesData?: ZappPipesData;
};

type onPressReturnFn =
  | ((_item?: ZappEntry | any, _index?: number) => Promise<void>)
  | (() => void);

export const useCellClick = ({
  component,
  zappPipesData,
  item,
}: Props): onPressReturnFn => {
  const { push, currentRoute } = useNavigation();
  const { pathname } = useRoute();

  const onCellTap: Option<Function> = React.useContext(CellTapContext);
  const actionExecutor = React.useContext(ActionExecutorContext);

  const cellSelectable = toBooleanWithDefaultTrue(
    component?.rules?.component_cells_selectable
  );

  const [__, setEntryContext] =
    ZappPipesEntryContext.useZappPipesContext(pathname);

  const logTimestamp = useProfilerLogging();

  const sendAnalyticsOnPress = useSendAnalyticsOnPress(
    item,
    component,
    zappPipesData
  );

  const onPress = React.useCallback(
    async (_item?: ZappEntry | any, _index?: number) => {
      // Making sure we are not getting GestureResponderEvent in here.
      const isZappEntry = _item?.id && _item?.type;
      const selectedItem = isZappEntry ? _item : item;
      setEntryContext?.(selectedItem);

      if (!selectedItem?.type?.value) {
        warnEmptyContentType(selectedItem);
      }

      sendAnalyticsOnPress(selectedItem, _index ?? 0);

      logTimestamp(selectedItem?.id?.toString());

      logOnPress(selectedItem, pathname, component, onCellTap);

      if (selectedItem) {
        await actionExecutor?.handleEntryActions(selectedItem);
      }

      if (selectedItem?.type?.value === "action") {
        if (selectedItem?.link?.href) {
          handleActionSchemeUrl({
            url: selectedItem.link.href,
          });
        }
      } else {
        if (isFunction(onCellTap)) {
          onCellTap?.(selectedItem, _index);
        } else {
          if (currentRoute === pathname || pathname.includes("video-modal")) {
            const targetScreen = component?.data?.target;

            push(
              R.when(
                () => targetScreen,
                R.mergeLeft({ screen_type: targetScreen })
              )(selectedItem)
            );
          }
        }
      }
    },
    [
      onCellTap,
      currentRoute,
      setEntryContext,
      pathname,
      push,
      sendAnalyticsOnPress,
    ]
  );

  const onPressRef = React.useRef<onPressReturnFn>();

  if (!cellSelectable) {
    // update ref with dummy function
    onPressRef.current = noop;
  } else {
    // update ref with the latest onPress function
    onPressRef.current = onPress;
  }

  return React.useCallback(onPressRef.current, []);
};
