import * as React from "react";
import { isEmpty } from "ramda";

import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigationUtils";
import { FocusableGroup } from "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup";
import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
import { StyleSheet } from "react-native";

import { Screen } from "../Screen/TV/index.web";
import { isLast } from "@applicaster/zapp-react-native-utils/arrayUtils";
import { ScreenContextProvider } from "../../Contexts/ScreenContext";

const styles = StyleSheet.create({
  container: { flex: 1 },
});

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

type Props = {
  Components: Components;
};

export const StackNavigator = ({ Components }: Props) => {
  const { mainStack } = useNavigation();

  const renderScreen = ({ route, state }, index) => {
    const pathAttributes = getPathAttributes({ pathname: route });

    if (isEmpty(pathAttributes)) {
      return null;
    }

    // HACK: Adding index to route to avoid conflicts in the navigator.
    // Startup hooks are all using PUSH navigation action to navigate, but their routes are always like root routes.
    // This means some hooks can have the same routes, e.g., ["hooks/context-setter", "/hooks/login-plug", "hooks/context-setter"].
    const routeId = `${route}--${index}`;

    return (
      <FocusableGroup
        id={route}
        preferredFocus={isLast(index, mainStack.length)}
        excludeFromFocusSearching
        key={routeId}
        style={styles.container}
      >
        <ScreenDataContext.Provider value={state}>
          <PathnameContext.Provider value={route}>
            <ScreenContextProvider pathname={route}>
              <Screen route={route} Components={Components} />
            </ScreenContextProvider>
          </PathnameContext.Provider>
        </ScreenDataContext.Provider>
      </FocusableGroup>
    );
  };

  return <>{mainStack.map(renderScreen)}</>;
};
