import * as React from "react";

import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";

import { useCellState } from "../MasterCell/utils";
import { FocusableGroup } from "../FocusableGroup";

type Props = {
  item: ZappEntry;
  CellRenderer: React.ComponentType<{ item: Object; state: string }>;
  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, setIsFocused] = React.useState(false);

  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 = React.useCallback(
    (value) => {
      setFocusedButtonId(value.focusedButtonId);

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

  const onGroupFocus = React.useCallback(() => {
    if (!skipFocusManagerRegistration) {
      setIsFocused(true);
    }
  }, [skipFocusManagerRegistration]);

  const onGroupBlur = React.useCallback(() => {
    if (!skipFocusManagerRegistration) {
      setIsFocused(false);
    }
  }, [skipFocusManagerRegistration]);

  return (
    <FocusableGroup
      id={`focusable-cell-wrapper-${id}`}
      testID={"cell-with-focusable-cell-renderer-focusable-group"}
      groupId={groupId}
      preferredFocus={preferredFocus}
      shouldUsePreferredFocus
      onFocus={onGroupFocus}
      onBlur={onGroupBlur}
    >
      <CellRenderer
        testID={"cell-with-focusable-cell-renderer"}
        item={item}
        groupId={`focusable-cell-wrapper-${id}`}
        onToggleFocus={handleToggleFocus}
        state={state}
        prefixId={id}
        focusedButtonId={focusedButtonId}
        preferredFocus={true}
        skipFocusManagerRegistration={skipFocusManagerRegistration}
        isFocusable={isFocusable}
        focused={focused}
      />
    </FocusableGroup>
  );
}
