import React, { ReactElement, useEffect, useState } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { runInAction } from 'mobx';
import { useCreatePickerContentState } from '../../hooks/usePickerContent';
import { PickerContentState } from '../../state';
import { PickerContentProps } from './PickerContent';
import { PickerContentAdditionalStep } from './PickerContentAdditionalStep';
import { PickerContentItemsSelection } from './PickerContentItemsSelection';
import { PickerContentBaseWrapped } from './PickerContentBaseWrapped';
import { fromMultipleSelectionToBoolean } from '../MaxSelection';
import { observer } from 'mobx-react-lite';
import type { PickerContentAdditionalStepProps } from './PickerContentAdditionalStep';
import { Box, Loader } from '@wix/design-system';

export interface PickerContentWrappedProps<T, F extends FiltersMap>
  extends PickerContentProps<T, F>,
    Pick<
      PickerContentAdditionalStepProps<T>,
      'autoAdditionalStepOnInitialSelect'
    > {
  renderPickerContent: (params: {
    state: PickerContentState<T, F>;
    renderItem: PickerContentProps<T, F>['renderItem'];
  }) => ReactElement;
}

function _PickerContentWrapped<T, F extends FiltersMap>(
  props: PickerContentWrappedProps<T, F>,
) {
  const {
    state: params,
    renderPickerContent,
    primaryButtonOnClick,
    backButtonOnClick,
    continueButtonOnClick,
  } = props;

  const createPickerContentState = useCreatePickerContentState();

  const [state] = useState(() =>
    params instanceof PickerContentState
      ? params
      : createPickerContentState(params),
  );

  useEffect(() => {
    return state.init({
      autoAdditionalStepOnInitialSelect:
        props.autoAdditionalStepOnInitialSelect,
    });
  }, [state]);

  const {
    isAdditionalStepShown,
    setIsAdditionalStepShown,
    isAutoAdditionalStepPending,
  } = state;

  const { picker, modalState } = state;
  const { _isModalOpen } = modalState;

  const primaryOnClick = ({
    currentLevel,
    numLevels,
  }: {
    currentLevel: number;
    numLevels: number;
  }) => {
    picker.onPrimaryButtonClick({ currentLevel, numLevels });
    runInAction(() => {
      modalState.onPrimaryButtonClick(
        state,
        state.additionalStep?.additionalData,
      );
    });
    primaryButtonOnClick?.();
  };

  const secondaryOnClick = () => {
    picker.onSecondaryButtonOnClick();
    _isModalOpen.value = false;
    props?.secondaryButtonOnClick?.();
  };

  const onCloseButtonClick = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
  ) => {
    picker.onCloseButtonClick();
    _isModalOpen.value = false;
    props?.onCloseButtonClick?.(event);
  };

  const {
    collection: { translate: t },
  } = picker;

  const selectedValue = picker.collection.bulkSelect.selectedValues?.[0];

  const hasAdditionalStep = React.useMemo(
    () =>
      selectedValue &&
      props?.hasAdditionalStep?.({
        item: selectedValue,
      }),
    [selectedValue, props?.hasAdditionalStep],
  );

  if (isAutoAdditionalStepPending) {
    return (
      <PickerContentBaseWrapped
        dataHook={props.dataHook}
        width={props.width}
        secondaryButtonText={t('cairo.cancel.button')}
        secondaryButtonOnClick={secondaryOnClick}
        onCloseButtonClick={onCloseButtonClick}
        primaryButtonProps={{ disabled: true }}
      >
        <Box
          height="100%"
          minHeight="300px"
          align="center"
          verticalAlign="middle"
        >
          <Loader dataHook="auto-additional-step-loader" />
        </Box>
      </PickerContentBaseWrapped>
    );
  }

  return isAdditionalStepShown ? (
    <PickerContentAdditionalStep
      {...props}
      pickerContentState={state}
      onBackButtonClick={() => {
        picker.onBackButtonClick();
        setIsAdditionalStepShown(false);
        backButtonOnClick?.({ item: selectedValue });
      }}
      primaryButtonOnClick={() => {
        primaryOnClick({ currentLevel: 2, numLevels: 2 });
      }}
      secondaryButtonOnClick={secondaryOnClick}
      onCloseButtonClick={onCloseButtonClick}
    />
  ) : (
    <PickerContentItemsSelection
      {...props}
      state={state}
      primaryButtonOnClick={() => {
        if (
          // currently additional step supports only single selection
          !fromMultipleSelectionToBoolean(props?.multiple) &&
          hasAdditionalStep &&
          selectedValue
        ) {
          picker.onContinueButtonClick();
          setIsAdditionalStepShown(true);
          continueButtonOnClick?.({ item: selectedValue });
        } else {
          primaryOnClick({ currentLevel: 1, numLevels: 1 });
        }
      }}
      primaryButtonText={
        hasAdditionalStep
          ? t('cairo.continue')
          : props.primaryButtonText || t('cairo.continue')
      }
      secondaryButtonOnClick={secondaryOnClick}
      renderPickerContent={renderPickerContent}
      onCloseButtonClick={onCloseButtonClick}
    />
  );
}

export const PickerContentWrapped = observer(_PickerContentWrapped);
