import { useEffect, useRef, useState } from 'react'
import styles from './Notification.module.css'

type Status = 'success' | 'error' | 'info' | 'warning'

interface Props {
  message: string
  status: Status
  onClose: () => void
  title?: string
  duration?: number
}

const ICONS: Record<Status, string> = {
  success: '✓',
  error: '✕',
  info: 'i',
  warning: '!',
}

const DEFAULT_TITLES: Record<Status, string> = {
  success: 'Успех',
  error: 'Ошибка',
  info: 'Информация',
  warning: 'Внимание',
}

export function Notification({ message, status, onClose, title, duration }: Props) {
  const [closing, setClosing] = useState(false)
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  function handleClose() {
    setClosing(true)
  }

  function handleAnimationEnd() {
    if (closing) onClose()
  }

  function clearTimer() {
    if (timerRef.current !== null) {
      clearTimeout(timerRef.current)
      timerRef.current = null
    }
  }

  function startTimer() {
    if (duration) {
      clearTimer()
      timerRef.current = setTimeout(() => setClosing(true), duration)
    }
  }

  useEffect(() => {
    startTimer()

    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') setClosing(true)
    }

    window.addEventListener('keydown', handleKeyDown)

    return () => {
      clearTimer()
      window.removeEventListener('keydown', handleKeyDown)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [duration])

  const heading = title ?? DEFAULT_TITLES[status]
  const ariaLive = status === 'error' || status === 'warning' ? 'assertive' : 'polite'

  return (
    <div
      className={`${styles.notification} ${styles[status]} ${closing ? styles.closing : ''}`}
      onAnimationEnd={handleAnimationEnd}
      onMouseEnter={clearTimer}
      onMouseLeave={startTimer}
      role="alert"
      aria-live={ariaLive}
    >
      <div className={styles.notificationWrapper}>
        <span className={styles.icon}>{ICONS[status]}</span>
        <div className={styles.content}>
          <p className={styles.title}>{heading}</p>
          <p className={styles.message}>{message}</p>
        </div>
      </div>
      <button className={styles.close} onClick={handleClose} aria-label="Закрыть">✕</button>
    </div>
  )
}
