/** TODO: Remove this file when tvos FocusableGroup
 * behaviour is aligned to the web one
 * FocusableGroup should only send onFocus and onBlur events when
 * Focus enters and leaves the Focusables inside the branch
 */
import * as React from "react";

import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";

import { isAppleTV } from "../../Helpers/Platform";
import { useCellState } from "../MasterCell/utils";

const useCellFocusedState = (
  skipFocusManagerRegistration: boolean,
  groupId: string,
  id: string
) => {
  const [currentCellFocused, setCurrentCellFocused] = React.useState(false);

  React.useEffect(() => {
    const isGroupItemFocused = () => {
      if (!skipFocusManagerRegistration) {
        const isFocused = focusManager.isGroupItemFocused(groupId, id);
        setCurrentCellFocused(isFocused);
      }
    };

    const handler = () => {
      // tvOS hack for properly checking focus
      if (isAppleTV()) {
        setTimeout(() => {
          isGroupItemFocused();
        }, 0);
      } else {
        isGroupItemFocused();
      }
    };

    focusManager.on(FOCUS_EVENTS.FOCUS, handler);

    return () => {
      focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
    };
  }, [groupId, skipFocusManagerRegistration]);

  return currentCellFocused;
};

type Props = {
  item: ZappEntry;
  CellRenderer: React.FunctionComponent<any>;
  id: string;
  groupId: string;
  onFocus: Function;
  index: number;
  scrollTo: Function;
  preferredFocus?: boolean;
  skipFocusManagerRegistration?: boolean;
  isFocusable?: boolean;
  behavior: Behavior;
  focused?: boolean;
};

export function CellWithFocusable(props: Props) {
  const {
    index,
    item,
    CellRenderer,
    id,
    groupId,
    onFocus,
    scrollTo = noop,
    preferredFocus,
    skipFocusManagerRegistration,
    isFocusable,
    behavior,
    focused,
  } = props;

  const isFocused = useCellFocusedState(
    skipFocusManagerRegistration,
    groupId,
    id
  );

  const state = useCellState({
    id: item.id,
    behavior,
    focused: isFocused || toBooleanWithDefaultFalse(focused),
  });

  const [focusedButtonId, setFocusedButtonId] = React.useState(undefined);

  // for horizontal scrolling
  React.useEffect(() => {
    if (focusedButtonId) {
      scrollTo(index);
    }
  }, [focusedButtonId]);

  const handleToggleFocus = (value) => {
    setFocusedButtonId(value.focusedButtonId);

    if (value.focusable) {
      onFocus(value.focusable, value.mouse);
    }
  };

  return (
    <CellRenderer
      item={item}
      groupId={groupId}
      onToggleFocus={handleToggleFocus}
      state={state}
      prefixId={id}
      focusedButtonId={focusedButtonId}
      preferredFocus={preferredFocus}
      skipFocusManagerRegistration={skipFocusManagerRegistration}
      isFocusable={isFocusable}
      focused={focused}
    />
  );
}
