import { PickerModalState } from '../../hooks';
import React, { ReactElement, ReactNode, useMemo } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { PromiseStatusError } from '@wix/bex-utils';
import {
  Box,
  CustomModalLayout,
  CustomModalLayoutProps,
  Loader,
} from '@wix/design-system';
import { useReactive } from '@wix/bex-utils/react';

export interface PickerModalSplashProps<T, F extends FiltersMap>
  extends Partial<CustomModalLayoutProps> {
  state: PickerModalState<T, F>;
  renderError: (params: { err: unknown; isOnline: boolean }) => ReactElement;
}

export function PickerModalSplash<T, F extends FiltersMap = FiltersMap>(
  props: PickerModalSplashProps<T, F>,
) {
  const { state, renderError, onCloseButtonClick, ...rest } = props;
  const {
    minContentHeight,
    fetchPickerComponent,
    fetchFirstPage,
    fetchInitialProps,
    _isModalOpen,
  } = state;

  const fetchPickerComponentStatus = useReactive(fetchPickerComponent.status);
  const fetchFirstPageStatus = useReactive(fetchFirstPage.status);
  const fetchInitialPropsStatus = useReactive(fetchInitialProps.status);

  const fetchStatuses = useMemo(
    () => [
      fetchPickerComponentStatus,
      fetchFirstPageStatus,
      fetchInitialPropsStatus,
    ],
    [fetchPickerComponentStatus, fetchFirstPageStatus, fetchInitialPropsStatus],
  );

  const errorStatus = useMemo(() => {
    return fetchStatuses.find(
      (status): status is PromiseStatusError => status.type === 'error',
    );
  }, [fetchStatuses]);

  const isFetching = useMemo(() => {
    return fetchStatuses.some(
      (status) => status.type === 'loading' || status.type === 'idle',
    );
  }, [fetchStatuses]);

  let child: ReactNode;

  if (errorStatus) {
    child = renderError({
      err: errorStatus.error,
      isOnline: true,
    });
    child = (
      <Box
        dataHook="splash-error-container"
        align="center"
        verticalAlign="middle"
        padding="SP6"
        minHeight={minContentHeight}
        boxSizing="border-box"
      >
        {child}
      </Box>
    );
  } else if (isFetching) {
    child = (
      <Box height={minContentHeight} align="center" verticalAlign="middle">
        <Loader dataHook="splash-loader" />
      </Box>
    );
  }

  return (
    <CustomModalLayout
      removeContentPadding
      closeButtonProps={{
        onClick: (event) => {
          _isModalOpen.value = false;
          onCloseButtonClick?.(event);
        },
        autoFocus: true,
      }}
      {...rest}
    >
      {child}
    </CustomModalLayout>
  );
}
