import React from "react";
import { last } from "ramda";
import { StyleSheet, View } from "react-native";
import {
  findMenuPlugin,
  getNavigationProps,
  getPathAttributes,
} from "@applicaster/zapp-react-native-utils/navigationUtils";
import {
  useIsScreenActive,
  useNavigation,
} from "@applicaster/zapp-react-native-utils/reactHooks";
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
import {
  useNavbarState,
  useScreenBackgroundColor,
} from "@applicaster/zapp-react-native-utils/reactHooks/screen";
import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";

import { NavBarContainer } from "../../Layout/TV/NavBarContainer";
import { ScreenResolver } from "../../ScreenResolver";
import { useInitialFocus } from "./hooks";
import { isPlayerPlugin } from "@applicaster/zapp-react-native-utils/pluginUtils";
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils";
import { FreezeWithCallback } from "../../FreezeWithCallback";

const styles = StyleSheet.create({
  container: {
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
});

type Components = {
  NavBar: React.ComponentType<any>;
  Background: React.ComponentType<any>;
};

type Props = {
  route: string;
  Components: Components;
};

const getActiveRiver = ({
  screenId,
  screenType,
  routeState,
  rivers,
  fallbackActiveRiver,
}) => {
  if (rivers[screenId]) {
    if (screenType === "hooks") {
      const navigations = routeState?.state?.entry?.payload?.navigations;

      if (navigations) {
        return routeState.state.entry.payload;
      }
    }

    return routeState?.state?.screen;
  }

  // screenId is not presented into rivers, use fallback instead
  return fallbackActiveRiver;
};

const getNavigations = ({
  screenId,
  screenType,
  routeState,
  rivers,
  fallbackNavigations,
}) => {
  if (rivers[screenId]) {
    // river presents
    if (screenType === "hooks") {
      const navigations = routeState?.state?.entry?.payload?.navigations;

      if (navigations) {
        return navigations;
      }
    }

    return routeState?.state?.screen?.navigations;
  }

  // screenId is not presented into rivers, use fallback instead
  return fallbackNavigations;
};

export const Screen = ({ route, Components }: Props) => {
  if (isNilOrEmpty(route)) {
    throw Error("Required props: route is missing");
  }

  const navigator = useNavigation();
  const { plugins = [], rivers = [] } = usePickFromState(["plugins", "rivers"]);

  const pathAttributes = getPathAttributes({ pathname: route });
  const routeState = navigator.getStackForPathname(route);

  const { screenType, screenId } = last(pathAttributes);

  const backgroundColor = useScreenBackgroundColor(screenId);

  useInitialFocus();

  const activeRiver = getActiveRiver({
    screenId,
    screenType,
    routeState,
    rivers,
    fallbackActiveRiver: navigator.activeRiver,
  });

  const navigationProps = getNavigationProps({
    navigator: {
      // @ts-ignore
      activeRiver,
      // @ts-ignore
      screenTitle: routeState.state.entry?.title || routeState.screen?.name,
    },
    category: "menu",
  });

  const navigations = getNavigations({
    screenId,
    screenType,
    routeState,
    rivers,
    fallbackNavigations: navigator.activeRiver.navigations,
  });

  const menuPlugin = findMenuPlugin(navigations, plugins);

  const NavBar = (Components.NavBar ||
    menuPlugin.module) as React.ComponentType<any>;

  const isPlayer = isPlayerPlugin(routeState);

  const { visible: isNavBarVisible } = useNavbarState();

  const screenData =
    screenType === "hooks" || isPlayer
      ? routeState?.state?.entry
      : routeState?.state?.screen;

  const isScreenActive = useIsScreenActive();

  return (
    <FreezeWithCallback
      freeze={!isScreenActive}
      onRelease={() => {
        focusManager.setInitialFocus();
      }}
    >
      <View style={[styles.container, { backgroundColor }]}>
        <NavBarContainer isVisible={isNavBarVisible} onReady={noop}>
          <NavBar
            isVisible={isNavBarVisible}
            menuPlugin={menuPlugin}
            navigationProps={navigationProps}
          />
        </NavBarContainer>
        <ScreenResolver
          screenType={screenType}
          screenId={screenId}
          screenData={screenData}
          groupId={route}
        />
      </View>
    </FreezeWithCallback>
  );
};
