import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
import { find, path } from "ramda";

import {
  waitForActiveScreen,
  waitForContent,
  getContentNode,
  getNavbarNode,
} from "./utils";

import { coreLogger } from "../../logger";

const logger = coreLogger.addSubsystem("focusManagerAux");

export async function setFocusOnMenu(currentRoute: string) {
  const { setFocus, focusableTree } = focusManager;

  try {
    await waitForActiveScreen(currentRoute, focusableTree);

    const navbar = getNavbarNode(focusableTree);

    const selectedMenuItemId = find(
      (child) => child.component.props.selected,
      navbar.children
    )?.id;

    if (selectedMenuItemId) {
      // set focus on selected menu item
      setFocus(selectedMenuItemId);

      return;
    }

    const firstMenuItemId = path(["children", 0, "id"], navbar);

    if (firstMenuItemId) {
      // set focus on first menu item
      setFocus(firstMenuItemId);
    }
  } catch (error) {
    logger.log({
      message: "setFocusOnMenu – failed to put focus on top-menu",
      data: {
        currentRoute,
        error,
      },
    });
  }
}

export async function setFocusOnContent(currentRoute: string) {
  // we need to put focus on content here
  // For doing it we have to wait registration of first focusable node into focusableTree
  // we wait until content node starts having children

  const { setInitialFocus, focusableTree } = focusManager;

  try {
    await waitForActiveScreen(currentRoute, focusableTree);
    await waitForContent(focusableTree);

    const content = getContentNode(focusableTree);

    const { success } = setInitialFocus(content);

    if (!success) {
      // we've failed to put initial focus on content, re-run "setFocusOnContent" again as a fallback
      throw Error(
        "we've failed to put initial focus on content, re-run 'setFocusOnContent' again as a fallback"
      );
    }
  } catch (error) {
    setFocusOnContent(currentRoute);
  }
}
