import { type ComponentType, Suspense } from 'react';

import Skeleton from '../components/design-system/Skeleton';

import { useModal } from './useModal';

const DEFAULT_FALLBACK_WIDTH = 600;
const DEFAULT_FALLBACK_HEIGHT = 255;

/** Skeleton size while the lazy modal chunk loads. */
export type LazyModalFallbackOptions = {
  width?: number;
  height?: number;
};

type ModalContentProps<T> = T & { onClose: () => void };

/**
 * useModal + Suspense: shows a Skeleton until the lazy modal loads.
 * Pass a component from `React.lazy()` for code-splitting.
 *
 * @example
 * const MyModal = lazy(() => import('./MyModal'));
 * const { modal, showModal, closeModal } = useLazyModal(MyModal);
 */
export function useLazyModal<T extends Record<string, unknown>>(
  ModalContent: ComponentType<ModalContentProps<T>>,
  fallbackOptions?: LazyModalFallbackOptions,
) {
  const width = fallbackOptions?.width ?? DEFAULT_FALLBACK_WIDTH;
  const height = fallbackOptions?.height ?? DEFAULT_FALLBACK_HEIGHT;

  return useModal((props: ModalContentProps<T>) => (
    <Suspense
      fallback={
        <Skeleton
          width={width}
          height={height}
        />
      }
    >
      <ModalContent {...props} />
    </Suspense>
  ));
}
