/// <reference types="@applicaster/applicaster-types" />
import React from "react";
import { AccessibilityInfo, findNodeHandle, View } from "react-native";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";

import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
import {
  getNavBarProps,
  getScreenId,
  shouldNavBarDisplayMenu,
} from "@applicaster/zapp-react-native-utils/navigationUtils";
import {
  useCurrentScreenData,
  useIsScreenActive,
  useNavbarState,
  useNavigation,
  useRoute,
  useScreenData,
} from "@applicaster/zapp-react-native-utils/reactHooks";
import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
import {
  isValidColor,
  isTransparentColor,
} from "@applicaster/zapp-react-native-utils/colorUtils";

import { RouteManager } from "../RouteManager";
import { useScreenConfiguration } from "../River/useScreenConfiguration";
import { useWaitForValidOrientation } from "./hooks";

const screenStyles = {
  flex: 1,
  paddingTop: 0,
  // paddingBottom: insets.bottom, // Should be applied directly by UI plugin
  // paddingLeft: insets.left, // Should be applied directly by UI plugin
  // paddingRight: insets.right, // Should be applied directly by UI plugin
};

type Props = {
  pathname: unknown;
  screenData: unknown;
};

export function Screen(_props: Props) {
  const theme = useTheme<BaseThemePropertiesMobile>();
  const navigation = useNavigation();
  const { plugins } = usePickFromState(["plugins"]);

  // Gets the data for the current screen configuration
  const currentScreenData = useCurrentScreenData();
  const { backgroundColor } = useScreenConfiguration(currentScreenData.id);

  const { screenData, pathname } = useRoute();

  const currentRiver = useScreenData(
    getScreenId(screenData, navigation.activeRiver)
  );

  const { title } = useNavbarState();

  const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);

  const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
    () => getNavBarProps(currentRiver, pathname, title),
    [currentRiver, pathname, title]
  );

  const NavBar = React.useMemo(
    () =>
      getNavigationPluginModule(
        "nav_bar",
        currentRiver,
        plugins
      ) as React.ComponentType<MobileNavBarPluginProps & { hasMenu: boolean }>,
    []
  );

  const offlinePlugin = getComponentModule({
    plugins,
    components: {},
    componentType: "offline-experience",
  });

  const { OfflineFallbackScreen } = offlinePlugin;

  const style = React.useMemo(
    () => ({
      ...screenStyles,
      backgroundColor:
        isValidColor(backgroundColor) && !isTransparentColor(backgroundColor)
          ? backgroundColor
          : theme.app_background_color,
    }),
    [theme.app_background_color, backgroundColor]
  );

  const isActive = useIsScreenActive();

  const ref = React.useRef(null);
  const isOrientationReady = useWaitForValidOrientation();

  // Playable screens handle their own orientation via the native player plugin,
  // so we skip the orientation wait gate to avoid a deadlock where the screen
  // waits for landscape but blocks rendering that would trigger the rotation.
  const isPlayableRoute = pathname?.includes("/playable");
  const isReady = isOrientationReady || isPlayableRoute;

  React.useEffect(() => {
    if (ref.current && isActive && isReady) {
      const nodeHandle = findNodeHandle(ref.current);

      if (nodeHandle != null) {
        AccessibilityInfo.setAccessibilityFocus(nodeHandle);
      }
    }
  }, [isActive, isReady]);

  // We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
  // This saves unnecessary re-renders and user will not see distorted aspect screen.
  return (
    <View
      ref={ref}
      style={style}
      importantForAccessibility={!isActive ? "no-hide-descendants" : "yes"}
    >
      {isReady ? (
        <>
          {navBarProps ? <NavBar {...navBarProps} hasMenu={hasMenu} /> : null}

          <OfflineFallbackScreen>
            {/* @TODO RouteManager doesn't use props, can they be removed ?  */}
            <RouteManager pathname={pathname} screenData={screenData} />
          </OfflineFallbackScreen>
        </>
      ) : null}
    </View>
  );
}
