import { useEffect, useRef, useState } from 'react';

import type { TransitionInOut2Api } from '~/src/components/TransitionInOut2';
import type { FC } from 'react';

import Box from '~/src/components/Box';
import Notification, { NotificationType } from '~/src/components/Notification';
import TransitionInOut from '~/src/components/TransitionInOut2';
import useIsLargeScreen from '~/src/hooks/useIsLargeScreen';

const DEFAULT_TIMEOUT_SECS = 3;

interface ToastProps {
  text: string;
  type?: NotificationType;
  testId?: string;
}

export interface ToasterProps {
  zIndex?: number;
  item?: ToastProps & {
    timeoutSecs?: number;
  };

  onHidden: () => void;
}

const Toast: FC<ToastProps & { onDismiss(): void }> = ({
  text,
  type = NotificationType.SUCCESS,
  testId,
  onDismiss,
}) => {
  const isLargeScreen = useIsLargeScreen();

  return (
    <Box
      testId="toast"
      maxWidth="120rem"
      minWidth={isLargeScreen ? '35rem' : '100%'}
      padding={isLargeScreen ? '2.4rem' : '1.6rem'}
      pointerEvents="all"
    >
      <Notification
        testId={testId}
        type={type}
        content={text}
        onDismiss={onDismiss}
      />
    </Box>
  );
};

const Toaster: FC<ToasterProps> = ({ zIndex, item, onHidden }) => {
  const [activeItem, setActiveItem] = useState(item);
  const transitionApiRef = useRef<TransitionInOut2Api>(null);

  useEffect(() => {
    if (!item) return;

    const { timeoutSecs = DEFAULT_TIMEOUT_SECS, ...toastProps } = item;

    setActiveItem(toastProps);

    transitionApiRef.current?.setVisible(true);

    const timeout = setTimeout(async () => {
      await transitionApiRef.current?.setVisible(false);
      onHidden();
    }, timeoutSecs * 1000);

    return () => {
      clearTimeout(timeout);
    };
  }, [item]);

  if (!activeItem) return null;

  return (
    <TransitionInOut
      positionAbsolute
      bottom={0}
      left={0}
      right={0}
      zIndex={zIndex}
      duration={200}
      pointerEvents="none"
      style={{ overflow: 'hidden' }}
      isVisibleInitial={false}
      apiRef={transitionApiRef}
      centerContent
      styleFrom={{
        transform: 'translateY(2rem)',
        opacity: 0,
      }}
    >
      <Toast {...activeItem} onDismiss={onHidden} />
    </TransitionInOut>
  );
};

export default Toaster;
