import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import Portal from '../components/Portal.jsx';
import StatusIcon from '../components/StatusIcon.jsx';

const TOAST_TIMEOUT = 4000;

const NoticesContext = createContext(null);

let nextId = 1;

/**
 * Toasts and alert dialogs for the whole app.
 *
 * - success / warning / error: top-right toast, auto-dismissing (paused while hovered or focused).
 * - alert: centred dialog that stays until dismissed (replaces the old custom popup).
 */
export const NoticesProvider = ({ children }) => {
  const [toasts, setToasts] = useState([]);
  const [dialog, setDialog] = useState(null);

  const dismissToast = useCallback((id) => {
    setToasts((current) => current.filter((item) => item.id !== id));
  }, []);

  const toast = useCallback((type, title, content = '') => {
    const id = nextId++;
    setToasts((current) => [...current, { id, type, title, content }]);
    return id;
  }, []);

  const alert = useCallback((type, title, content = '') => {
    setDialog({ type, title, content });
  }, []);

  const value = useMemo(
    () => ({
      success: (title, content) => toast('success', title, content),
      warning: (title, content) => toast('warning', title, content),
      error: (title, content) => toast('error', title, content),
      alert,
    }),
    [toast, alert]
  );

  return (
    <NoticesContext.Provider value={value}>
      {children}
      <Portal>
        <div className="osgsw-toasts" aria-live="polite">
          {toasts.map((item) => (
            <Toast key={item.id} {...item} onDismiss={dismissToast} />
          ))}
        </div>
        {dialog && <AlertDialog {...dialog} onClose={() => setDialog(null)} />}
      </Portal>
    </NoticesContext.Provider>
  );
};

const Toast = ({ id, type, title, content, onDismiss }) => {
  const [paused, setPaused] = useState(false);

  useEffect(() => {
    if (paused) return undefined;
    const timer = setTimeout(() => onDismiss(id), TOAST_TIMEOUT);
    return () => clearTimeout(timer);
  }, [id, paused, onDismiss]);

  return (
    <div
      className={`osgsw-toast osgsw-toast--${type}`}
      role={type === 'error' ? 'alert' : 'status'}
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      onFocus={() => setPaused(true)}
      onBlur={() => setPaused(false)}
    >
      <StatusIcon type={type} />
      <div className="osgsw-toast__body">
        <strong>{title}</strong>
        {content && <p>{content}</p>}
      </div>
      <button type="button" className="osgsw-toast__close" onClick={() => onDismiss(id)} aria-label="Dismiss">
        &times;
      </button>
    </div>
  );
};

const AlertDialog = ({ type, title, content, onClose }) => {
  const buttonRef = useRef(null);

  useEffect(() => {
    const previousFocus = document.activeElement;
    if (buttonRef.current) buttonRef.current.focus();
    const onKeyDown = (e) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKeyDown);
    return () => {
      document.removeEventListener('keydown', onKeyDown);
      if (previousFocus && previousFocus.focus) previousFocus.focus();
    };
  }, [onClose]);

  return (
    <div className="osgsw-dialog-backdrop" onClick={onClose} role="presentation">
      <div
        className={`osgsw-dialog osgsw-dialog--${type}`}
        role="alertdialog"
        aria-modal="true"
        aria-labelledby="osgsw-dialog-title"
        onClick={(e) => e.stopPropagation()}
      >
        <StatusIcon type={type} className="osgsw-dialog__icon" />
        <h2 id="osgsw-dialog-title">{title}</h2>
        {content && <p>{content}</p>}
        <button ref={buttonRef} type="button" className="osgsw-button osgsw-button--primary" onClick={onClose}>
          Okay
        </button>
      </div>
    </div>
  );
};

export const useNotices = () => useContext(NoticesContext);
