import { useEffect, useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import styles from './toast.module.css';

export type ToastType = 'success' | 'error' | 'info';

export interface ToastItem {
  readonly id: string;
  readonly message: string;
  readonly type: ToastType;
  readonly duration: number;
}

interface ToastProps {
  readonly toasts: readonly ToastItem[];
  readonly onDismiss: (id: string) => void;
}

export function ToastContainer({ toasts, onDismiss }: ToastProps) {
  const { t } = useTranslation();
  return (
    <div className={styles.container} aria-live="polite" aria-label={t('toast.notifications')}>
      {toasts.map((toast) => (
        <ToastEntry key={toast.id} toast={toast} onDismiss={onDismiss} />
      ))}
    </div>
  );
}

interface ToastEntryProps {
  readonly toast: ToastItem;
  readonly onDismiss: (id: string) => void;
}

function ToastEntry({ toast, onDismiss }: ToastEntryProps) {
  const { t } = useTranslation();
  const [exiting, setExiting] = useState(false);

  const handleDismiss = useCallback(() => {
    setExiting(true);
    setTimeout(() => onDismiss(toast.id), 200);
  }, [toast.id, onDismiss]);

  useEffect(() => {
    const timer = setTimeout(() => {
      handleDismiss();
    }, toast.duration);

    return () => clearTimeout(timer);
  }, [toast.duration, handleDismiss]);

  const typeClass = styles[toast.type] ?? '';
  const className = [styles.toast, typeClass, exiting ? styles.exiting : '']
    .filter(Boolean)
    .join(' ');

  return (
    <div className={className} role="status">
      <span className={styles.message}>{toast.message}</span>
      <button
        className={styles.dismiss}
        onClick={handleDismiss}
        aria-label={t('toast.dismiss')}
        type="button"
      >
        &#10005;
      </button>
    </div>
  );
}
