import React from "react";
import { View, ButtonProps } from "react-native";
import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
import * as R from "ramda";
import { useInitialFocus } from "@applicaster/zapp-react-native-utils/focusManager";
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
import { useFocusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable/index.android";
import {
  useIsRTL,
  applyRTLStylesIfNeeded,
} from "@applicaster/zapp-react-native-utils/localizationUtils";

const { Logger } = getXray();

import {
  cloneElementsWithIds,
  insertBetween,
  recursiveCloneElementsWithState,
  useFilterChildren,
} from "../../../utils";

import type {
  HorizontalSeparatorProps,
  ContainerProps,
  ContainerChildren,
} from "./types";

const logger = new Logger("plugin", "plugins/navigation-action");

const generateId = (cellUUID, suffixId) => `${cellUUID}--${suffixId}`;

const HorizontalSeparator = ({ width }: HorizontalSeparatorProps) => (
  <View style={{ width }} />
);

export function ButtonContainerView({
  style,
  children,
  ...otherProps
}: ContainerProps) {
  const isRTL = useIsRTL();

  const horizontalGutter = R.pathOr(0, ["horizontalGutter"], otherProps);

  const filteredChildren = useFilterChildren<ContainerChildren>(children);

  const buttonIds = filteredChildren.map((child) => {
    const { cellUUID, suffixId } = child.props;

    return generateId(cellUUID, suffixId);
  });

  useInitialFocus(otherProps.state === "focused", R.head(buttonIds));

  if (R.isEmpty(filteredChildren)) {
    return null;
  }

  return (
    <View style={applyRTLStylesIfNeeded(style, isRTL)}>
      {insertBetween(
        (index) => (
          <HorizontalSeparator
            key={`separator_${index}`}
            width={horizontalGutter}
          />
        ),
        cloneElementsWithIds(buttonIds, filteredChildren)
      )}
    </View>
  );
}

export function FocusableViewComponent(
  { style, children, item, ...otherProps }: ButtonProps,
  ref
) {
  const {
    cellUUID,
    groupId,
    suffixId,
    normalStyles,
    focusedStyles,
    nextFocusLeft,
    nextFocusRight,
    pluginIdentifier,
    disableFocus,
  } = otherProps;

  const parentFocus = useFocusable();

  const actionContext = useActions(pluginIdentifier);

  const onPress = () => {
    if (!actionContext) {
      logger.warning(
        `Cannot resolve action context for ${pluginIdentifier} - please make sure the plugin is installed and up to date`
      );

      return;
    }

    actionContext?.invokeAction?.(item);
  };

  return (
    <Focusable
      id={generateId(cellUUID, suffixId)}
      disableFocus={disableFocus}
      groupId={groupId}
      onPress={onPress}
      nextFocusUp={parentFocus?.nextFocusUp}
      nextFocusDown={parentFocus?.nextFocusDown}
      nextFocusLeft={nextFocusLeft || parentFocus?.nextFocusLeft}
      nextFocusRight={nextFocusRight || parentFocus?.nextFocusRight}
      ref={ref}
    >
      {(isFocused) => {
        const additionalStyles = isFocused ? focusedStyles : normalStyles;

        return (
          <View
            style={{
              ...style,
              ...additionalStyles,
            }}
          >
            {recursiveCloneElementsWithState(isFocused, children)}
          </View>
        );
      }}
    </Focusable>
  );
}
