import * as R from "ramda";

import { ANALYTICS_CORE_EVENTS } from "../events";
import { log_error, log_debug } from "../logger";
import { isEmptyOrNil } from "../../cellUtils";
import {
  postAnalyticEvent,
  startAnalyticsTimedEvent,
  endAnalyticsTimedEvent,
} from "../manager";

type ScreenDataProps = {
  screen_entry_title?: string;
  screen_name?: string;
};

let previousAnalyticsScreenData: AnalyticsScreenProperties | null = null;

const screenDataPropsFromAnalyticsScreenProps = (
  screenData: AnalyticsScreenProperties
): ScreenDataProps | null => {
  if (R.isNil(screenData)) {
    return null;
  }

  return {
    screen_entry_title: screenData?.screen_entry_title,
    screen_name: screenData?.screen_name,
  };
};

// We can not check full AnalyticsScreenProperties object, since entry id could be different
// with raw feed data and after load it maybe changed. This is bug on Zapp
const screenDataNotEqual = (screenData: AnalyticsScreenProperties): boolean => {
  return R.not(
    R.equals(
      screenDataPropsFromAnalyticsScreenProps(previousAnalyticsScreenData),
      screenDataPropsFromAnalyticsScreenProps(screenData)
    )
  );
};

const clearPreviousAnalyticsScreenData = () => {
  previousAnalyticsScreenData = null;
};

const sendEndAnalyticsTimedEventIfNeeded = () => {
  if (isEmptyOrNil(previousAnalyticsScreenData?.screen_name)) {
    return;
  }

  endAnalyticsTimedEvent(
    previousAnalyticsScreenData?.screen_name as string,
    previousAnalyticsScreenData
  );

  clearPreviousAnalyticsScreenData();
};

const setPreviousData = (analyticsScreenData: AnalyticsScreenProperties) => {
  previousAnalyticsScreenData = analyticsScreenData;
};

export const sendScreenEvent = ({
  extraProps,
  analyticsScreenData,
}: AnalyticsDefaultProperties) => {
  if (!analyticsScreenData) {
    log_error(
      `sendScreenEvent: no screen data available to send analytics event ${ANALYTICS_CORE_EVENTS.SCREEN_VIEW}`
    );

    return;
  }

  if (
    R.isNil(analyticsScreenData?.screen_type) ||
    R.isNil(analyticsScreenData?.screen_layout_id)
  ) {
    return;
  }

  const forceReload = extraProps?.forceReload || false;
  const eventName = ANALYTICS_CORE_EVENTS.SCREEN_VIEW;

  const shouldSendScreenEvent =
    screenDataNotEqual(analyticsScreenData) || forceReload;

  const screenName = analyticsScreenData?.screen_name || "unknown screen";

  if (!shouldSendScreenEvent) {
    return;
  }

  sendEndAnalyticsTimedEventIfNeeded();
  startAnalyticsTimedEvent(screenName, analyticsScreenData);
  setPreviousData(analyticsScreenData);
  postAnalyticEvent(eventName, analyticsScreenData);

  log_debug(
    `sendScreenEvent: send event: ${eventName}, screenName: ${screenName}`,
    {
      analyticsScreenData,
    }
  );
};
