import * as R from "ramda";
import * as React from "react";
import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
import {
  OfflineItemState,
  eventForEntry,
  eventForComponent,
} from "./AnalyticsEvents/helper";

import {
  sendOnClickEvent,
  sendMenuClickEvent,
  sendMenuToggleEvent,
  sendBackButtonClickEvent,
  sendOnNavItemClickEvent,
  sendHeaderClickEvent,
  sendHardwareBackButtonClickEvent,
  sendDownloadsEvent,
  sendScreenEvent,
  sendSearchCanceledEvent,
  sendSearchExecutedEvent,
  sendShareInitiatedEvent,
  sendShareSuccessEvent,
} from "./AnalyticsEvents";

import { postAnalyticEvent } from "./manager";

import { ANALYTICS_CORE_EVENTS } from "./events";

import { noop } from "../functionUtils";

type ComponentWithChildrenProps = {
  children: React.ReactElement;
};

export function sendSelectCellEvent(item, component, headerTitle, itemIndex) {
  const analyticsProperties = R.compose(
    R.reject(R.isNil),
    R.mergeRight(eventForEntry(item, itemIndex + 1))
  )(eventForComponent(component, headerTitle));

  postAnalyticEvent(ANALYTICS_CORE_EVENTS.TAP_CELL, analyticsProperties);
}

export function sendLaunchEvent() {
  if (isWeb()) {
    // Launch event gets all of its data from Analytics Bridge
    postAnalyticEvent(ANALYTICS_CORE_EVENTS.LAUNCH_APP);
  }
}

type GetAnalyticsFunctionsArgs = Partial<{
  component?: ZappUIComponent;
  zappPipesData?: ZappPipesData;
  item?: ZappEntry;
}> &
  Record<string, any>;

type AnalyticsFunctions = {
  sendOnClickEvent: (props: AnalyticsDefaultProperties) => void;
  sendMenuClickEvent: (props: AnalyticsDefaultProperties) => void;
  sendMenuToggleEvent: (props: AnalyticsDefaultProperties) => void;
  sendOnNavItemClickEvent: (props: AnalyticsDefaultProperties) => void;
  sendHeaderClickEvent: (extraProps: ExtraProps) => void;
  sendScreenEvent: (props: AnalyticsDefaultProperties) => void;
  sendBackButtonClickEvent: () => void;
  sendHardwareBackButtonClickEvent: () => void;
  sendDownloadsEvent: (arg: {
    item: ZappEntry;
    state: OfflineItemState;
  }) => void;
  sendSearchCanceledEvent: (props: AnalyticsDefaultProperties) => void;
  sendSearchExecutedEvent: (props: AnalyticsDefaultProperties) => void;
  sendShareInitiatedEvent: (props: AnalyticsDefaultProperties) => void;
  sendShareSuccessEvent: (props: AnalyticsDefaultProperties) => void;
};

type GetAnalyticsFunctions = (
  options?: GetAnalyticsFunctionsArgs
) => void | AnalyticsFunctions;

export function getAnalyticsFunctions({
  component,
  zappPipesData,
  item,
}: GetAnalyticsFunctionsArgs): AnalyticsFunctions {
  return {
    sendOnClickEvent: (onClickProps: AnalyticsDefaultProperties) => {
      sendOnClickEvent({
        component,
        zappPipesData,
        analyticsScreenData: onClickProps.analyticsScreenData,
        extraProps: onClickProps?.extraProps,
      });
    },

    sendMenuClickEvent,
    sendMenuToggleEvent,
    sendBackButtonClickEvent,
    sendOnNavItemClickEvent,
    sendHeaderClickEvent: (extraProps: ExtraProps) => {
      sendHeaderClickEvent({
        component,
        zappPipesData,
        item,
        extraProps: extraProps,
      });
    },
    sendHardwareBackButtonClickEvent,
    sendScreenEvent,
    sendDownloadsEvent,
    sendSearchCanceledEvent,
    sendSearchExecutedEvent,
    sendShareInitiatedEvent,
    sendShareSuccessEvent,
  };
}

export const AnalyticsContext =
  React.createContext<GetAnalyticsFunctions>(noop);

export function AnalyticsProvider({ children }: ComponentWithChildrenProps) {
  return (
    // @ts-ignore - this is a valid context provider
    <AnalyticsContext.Provider value={getAnalyticsFunctions}>
      {children}
    </AnalyticsContext.Provider>
  );
}

export function useAnalytics(props?: GetAnalyticsFunctionsArgs): any {
  const { component, zappPipesData, item } = props || {};

  const getAnalyticsFunctions = React.useContext(AnalyticsContext);

  const analyticsFunctions = React.useMemo(
    () => getAnalyticsFunctions({ item, component, zappPipesData }),
    [item?.id, component?.id, zappPipesData, getAnalyticsFunctions]
  );

  return analyticsFunctions;
}
