import * as React from "react";
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
import {
  useBackHandler,
  useIsNavBarVisible,
} from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import { useHookAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
import { useSetNavbarState } from "@applicaster/zapp-react-native-utils/reactHooks";

import { componentsLogger } from "../../Helpers/logger";

const logger = componentsLogger.addSubsystem("HookRenderer");

const HOOK_PRESENTATION_TYPE = "Hook";

type Props = {
  focused?: boolean;
  parentFocus?: ParentFocus;
  screenData: HookPluginProps;
  callback: hookCallback;
};

const HookRenderer = (props: Props) => {
  const { focused, screenData, callback } = props;
  const { payload, hookPlugin } = screenData;

  const {
    module: { Component: HookComponent, presentFullScreen },
    configuration,
  } = hookPlugin;

  const { setVisible: showNavBar } = useSetNavbarState();

  useHookAnalytics(props);

  const isNavBarVisible = useIsNavBarVisible();

  useBackHandler(() => {
    callback({ success: false, payload, cancelled: true });

    return true;
  });

  React.useEffect(() => {
    if (presentFullScreen && isTV()) {
      showNavBar(false);
    }

    return () => {
      if (isTV()) {
        showNavBar(true);
      }
    };
  }, [showNavBar]);

  // Passing empty parentFocus if navbar is not visible (fullScreen hook)
  const parentFocus = isNavBarVisible ? props.parentFocus : {};

  return (
    <HookComponent
      {...{
        callback,
        payload,
        configuration,
        hookPlugin,
        focused,
        parentFocus,
        presentationType: HOOK_PRESENTATION_TYPE,
      }}
    />
  );
};

/**
 * Guard component to prevent rendering HookRenderer when screenData or hookPlugin is missing. This is to avoid potential crashes due to missing data.
 */
const HookRendererGuard = (props: Props) => {
  React.useEffect(() => {
    if (!props.screenData) {
      logger.error(
        "HookRenderer received no screenData, screen cannot be rendered"
      );
    } else if (!props.screenData.hookPlugin) {
      logger.error(
        "HookRenderer received screenData with no hookPlugin, screen cannot be rendered",
        {
          screenData: props.screenData,
        }
      );
    }
  }, [props.screenData]);

  if (!props.screenData || !props.screenData.hookPlugin) {
    return null;
  }

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

export { HookRendererGuard as HookRenderer };
