import React from "react";
import { View, ViewProps, ViewStyle } from "react-native";
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";

interface IProps {
  targetScreenId?: string;
  children?: React.ReactNode;
  style?: ViewStyle;
  extraOffset?: number;
}

type CombinedProps = IProps & ViewProps;
/**
 * The MarginTop is essentially a feature used for managing the visibility of components on your screen.
 * A more accurate term for this might be something like a 'component visibility threshold' or 'cut-off point'.
 * In practical terms, MarginTop determines a specific vertical position (given in the 'y' coordinate)
 * on your screen above which components aren't shown.
 * You might visualize this as a horizontal line across your screen, and any component crossing this line becomes invisible.
 *
 * Classic use case for this feature is making sure that component aren't displayed underneath the navigation bar.
 */

export const useMarginTop = (targetScreenId: string): number => {
  const theme = useTheme<BaseThemePropertiesTV>();
  const screenData = useCurrentScreenData(targetScreenId);
  const isGeneralContentScreen = screenData?.plugin_type === "general_content";
  const supportsUiComponents = screenData?.ui_components;

  /**
   * ScreenPicker is a component but should really be a screen.
   * We need to skip margin top for it as it's already applied to the target screen
   **/
  const isScreenPicker =
    screenData?.ui_components?.[0]?.component_type === "screen-picker-qb-tv";

  // ignore margin on screenPicker
  if (isScreenPicker) {
    return 0;
  }

  const isPlayer = screenData?.plugin_type === "player";

  // ignore margin on inlinePlayer (remove if better way of identifying cases for plugins that don't have marginTop)
  if (isPlayer) {
    return 0;
  }

  // Empty string means that value is blank in the CMS. Fallback to theme
  if (String(screenData?.styles?.screen_margin_top) === "") {
    return Number(theme.screen_margin_top);
  }

  /**
   *  If value is undefined it means one of three things
   *  1. Screen is not a general content screen and it doesn't handle ui components (return 0)
   *  2. Screen is a general content screen but it doesn't have a margin top value (return theme value)
   *  3. Screen isn't general content screen but it handles the ui components (return theme value)
   */
  if (screenData?.styles?.screen_margin_top === undefined) {
    if (isGeneralContentScreen || supportsUiComponents) {
      return Number(theme.screen_margin_top);
    }

    return 0;
  }

  return Number(screenData?.styles?.screen_margin_top);
};

export const TopMarginApplicator: React.FC<CombinedProps> = (
  props: CombinedProps
) => {
  const extraOffset = props?.extraOffset ?? 0;

  // HACK: Remove extraOffset when focusIssue with absolute elements is fixed on tvos
  const marginTop = useMarginTop(props.targetScreenId) + extraOffset;
  const style = { ...((props.style as {}) || {}), marginTop };

  // Then, spread the rest of the props on your returned JSX.
  return (
    <View {...props} style={style}>
      {props.children}
    </View>
  );
};
