/* Global toast / snackbar — replaces the original CMS's showToast()
   helper. Surfaces an ephemeral message in the bottom-right with
   tone-aware styling. Imperative API attaches to window so any module
   can call window.toast(msg, tone) without wiring through context.

   Tones: 'success' | 'warn' | 'danger' | 'info' (default).

   Usage:
     toast('Species saved');
     toast('Save failed: ' + err.message, 'danger');

   The tray component renders nothing until App mounts <ToastTray /> at
   the root. Toasts auto-dismiss after 4s by default; pass an explicit
   duration via { duration: ms } in the options. */

let _toastListeners = new Set();
let _toastSeq = 0;

function _emit(msg, tone, options) {
  const id = ++_toastSeq;
  const t = {
    id,
    message: String(msg || ''),
    tone: tone || 'info',
    duration: (options && options.duration) || 4000,
    action: options && options.action,
  };
  _toastListeners.forEach((fn) => fn(t));
  return id;
}

window.toast = function (msg, tone, options) {
  return _emit(msg, tone, options);
};
window.toast.success = (m, o) => _emit(m, 'success', o);
window.toast.warn    = (m, o) => _emit(m, 'warn', o);
window.toast.danger  = (m, o) => _emit(m, 'danger', o);
window.toast.error   = (m, o) => _emit(m, 'danger', o);
window.toast.info    = (m, o) => _emit(m, 'info', o);

/* Animation duration must match --aq-toast-out keyframe duration in
   styles.css (currently 200ms). */
const TOAST_EXIT_MS = 200;

function ToastTray() {
  const [items, setItems]     = useState([]);
  const [leaving, setLeaving] = useState(() => new Set());

  useEffect(() => {
    function onPush(t) {
      setItems((cur) => [...cur, t]);
      if (t.duration > 0) {
        setTimeout(() => startLeave(t.id), t.duration);
      }
    }
    _toastListeners.add(onPush);
    return () => { _toastListeners.delete(onPush); };
  }, []);

  function startLeave(id) {
    setLeaving((cur) => {
      const next = new Set(cur);
      next.add(id);
      return next;
    });
    setTimeout(() => {
      setItems((cur) => cur.filter((x) => x.id !== id));
      setLeaving((cur) => {
        const next = new Set(cur);
        next.delete(id);
        return next;
      });
    }, TOAST_EXIT_MS);
  }

  function dismiss(id) {
    startLeave(id);
  }

  if (items.length === 0) return null;

  const TONES = {
    success: { bg: 'color-mix(in srgb, var(--aq-success) 18%, var(--aq-surface))',
               border: 'color-mix(in srgb, var(--aq-success) 45%, transparent)',
               fg: 'var(--aq-success)' },
    warn:    { bg: 'color-mix(in srgb, var(--aq-warn) 18%, var(--aq-surface))',
               border: 'color-mix(in srgb, var(--aq-warn) 45%, transparent)',
               fg: 'var(--aq-warn)' },
    danger:  { bg: 'color-mix(in srgb, var(--aq-danger) 18%, var(--aq-surface))',
               border: 'color-mix(in srgb, var(--aq-danger) 45%, transparent)',
               fg: 'var(--aq-danger)' },
    info:    { bg: 'var(--aq-surface)',
               border: 'var(--aq-line)',
               fg: 'var(--aq-text)' },
  };

  return (
    <div style={{
      position: 'fixed', bottom: 16, right: 16, zIndex: 9999,
      display: 'flex', flexDirection: 'column', gap: 8,
      maxWidth: 'min(420px, calc(100vw - 32px))',
      pointerEvents: 'none',
    }}>
      {items.map((t) => {
        const tone = TONES[t.tone] || TONES.info;
        const isLeaving = leaving.has(t.id);
        return (
          <div
            key={t.id}
            className={isLeaving ? 'aq-toast is-leaving' : 'aq-toast'}
            style={{
              pointerEvents: 'auto',
              background: tone.bg,
              border: `1px solid ${tone.border}`,
            }}
          >
            <span className="aq-toast-dot" style={{ background: tone.fg }} />
            <div className="aq-toast-msg">{t.message}</div>
            {t.action && (
              <button
                className="aq-toast-action"
                style={{ color: tone.fg }}
                onClick={() => { try { t.action.fn(); } catch (_) {} dismiss(t.id); }}
              >{t.action.label}</button>
            )}
            <button
              className="aq-toast-close"
              onClick={() => dismiss(t.id)}
              aria-label="Dismiss"
            ><Icon name="close" size={11} /></button>
          </div>
        );
      })}
    </div>
  );
}

window.ToastTray = ToastTray;
