/// <reference types="@applicaster/applicaster-types" />
import React from "react";
import { View } from "react-native";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
import {
  isOrientationCompatible,
  useGetScreenOrientation,
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";

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

import { RouteManager } from "../RouteManager";
import { useScreenConfiguration } from "../River/useScreenConfiguration";
import { isValidColor } from "./utils";

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 {
    width: screenWidth,
    height,
    deviceInfo,
  } = useDimensions("screen", {
    fullDimensions: true,
  });

  const { screenData, pathname } = useRoute();

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

  const { title } = useNavbarState();

  const isTablet = deviceInfo?.isTablet;

  const { appData } = usePickFromState(["appData"]);
  const isTabletPortrait = appData?.isTabletPortrait;

  const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };

  const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);

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

  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)
        ? backgroundColor
        : theme.app_background_color,
    }),
    [theme.app_background_color, backgroundColor]
  );

  const targetScreenData =
    currentScreenData || (screenData as any)?.targetScreen || screenData;

  const orientation = useGetScreenOrientation(targetScreenData);

  // 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.
  if (
    !isOrientationCompatible({
      orientation,
      layoutData,
    })
  ) {
    return <View style={style} />;
  }

  return (
    <View style={style}>
      {navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}

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