import { CustomModalLayoutProps, Modal, ModalProps } from '@wix/design-system';
import React, { ReactElement, ReactNode, useEffect, useState } from 'react';
import { PickerModalState } from '../../hooks';
import { FiltersMap } from '@wix/bex-core';
import { useReactive } from '@wix/bex-utils/react';
import { PickerModalSplash } from '../PickerModalSplash';
import { MultipleSelection } from '../MaxSelection';

export interface PickerModalProps<T, F extends FiltersMap = FiltersMap>
  extends Partial<CustomModalLayoutProps> {
  /**
   * Optional props to forward to `Modal` component
   */
  modalProps?: Partial<ModalProps>;
  /** State object created with [`usePickerModal`](./?path=/story/base-components-collections-picker-hooks--usepickermodal) */
  state: PickerModalState<T, F>;
  /**
   * A component to be rendered in the modal content when there's a failure fetching the data
   * @param params
   * @param params.err - The original failure error object
   * @param params.isOnline - Indicates whether internet connection is available or not
   */
  renderError: (params: { err: unknown; isOnline: boolean }) => ReactElement;
  /**
   * Limits the number of items that can be selected.<br>
   * Either a boolean or a number. A number indicates the maximum number of selections, `true` indicates no limit, `false` indicates only 1 item (radio button will be shown instead of checkboxes)
   */
  multiple?: MultipleSelection;
}

export function PickerModal<T, F extends FiltersMap = FiltersMap>(
  props: PickerModalProps<T, F>,
) {
  const {
    dataHook,
    state,
    modalProps,
    renderError,
    width = '618px',
    multiple,
    ...rest
  } = props;
  const {
    _isModalOpen,
    _customContent,
    _isCustomContentVisible,
    fetchPickerComponent,
    fetchFirstPage,
    fetchInitialProps,
  } = state;

  const isModalOpen = useReactive(_isModalOpen);
  const fetchPickerComponentStatus = useReactive(fetchPickerComponent.status);
  const fetchFirstPageStatus = useReactive(fetchFirstPage.status);
  const fetchInitialPropsStatus = useReactive(fetchInitialProps.status);
  const customContent = useReactive(_customContent);
  const isCustomContentVisible = useReactive(_isCustomContentVisible);

  useState(() => {
    state.multipleRef.current = multiple;
  });

  useEffect(() => {
    state.multipleRef.current = multiple;
  }, [multiple]);

  useEffect(() => {
    state.onIsOpenChanged();
  }, [isModalOpen]);

  useEffect(() => state.init(), []);

  let child: ReactNode;

  if (
    fetchPickerComponentStatus.type === 'success' &&
    fetchFirstPageStatus.type === 'success' &&
    fetchInitialPropsStatus.type === 'success'
  ) {
    const { data: PickerContentComponent } = fetchPickerComponentStatus;

    child = (
      <PickerContentComponent
        dataHook={dataHook}
        width="100%"
        modalState={state}
        renderError={renderError}
        multiple={multiple}
        {...rest}
      />
    );
  } else {
    child = (
      <PickerModalSplash
        dataHook={dataHook}
        state={state}
        width="100%"
        renderError={renderError}
        {...rest}
        primaryButtonText={undefined}
        secondaryButtonText={undefined}
        primaryButtonOnClick={undefined}
        secondaryButtonOnClick={undefined}
      />
    );
  }

  return (
    <>
      <Modal
        dataHook={
          dataHook ? `${dataHook}-picker-modal` : 'picker-modal-lazy-modal'
        }
        onRequestClose={() => state.closeModal()}
        {...modalProps}
        isOpen={isModalOpen}
      >
        <div
          data-wix-patterns
          style={{ width, maxHeight: '100%', display: 'flex' }}
        >
          {child}
        </div>
      </Modal>

      {customContent?.({
        isOpen: isCustomContentVisible,
        width,
        close: state.onCreateNew,
      })}
    </>
  );
}
