import { t } from '../i18n/t';
import '../styles/Toast.css';

/**
 * Toast — host-level notification surface.
 *
 * Why this exists
 * ───────────────
 * The host occasionally needs to tell the user something: "link
 * copied", "upload failed", "add something to your design first."
 * Before the module split there was an in-App toast system that did
 * this; it got stripped along with the editor surface during the
 * split, and host operations have been silently throwing or
 * console.logging ever since. This restores the surface but scopes
 * it strictly to host concerns \u2014 the editor module has its own
 * internal toast catalog for editor concerns (crop blocked, etc.)
 * and that is deliberately not shared.
 *
 * Architecture
 * ────────────
 * State + scheduling live in App.jsx (showToast / dismissToast); this
 * file is just the renderer. App owns the state because:
 *   \u2022 Multiple host components could need to toast eventually
 *     (currently only App's own handlers do).
 *   \u2022 Lifting matches the existing host pattern (cart, isExporting,
 *     etc. all live in App) and avoids introducing a Context for a
 *     surface this small.
 *   \u2022 Timer lifecycle is co-located with the state it modifies,
 *     which keeps the cancel-on-unmount + re-schedule-cancels-prior
 *     semantics straightforward.
 *
 * If the toast surface grows (more callers, error boundaries that
 * need to surface from anywhere in the tree), refactor to a
 * ToastContext + useToast() hook. For now, prop-passing the
 * showToast callback to anything outside App that needs it is the
 * simpler path.
 *
 * Toast shape
 * ───────────
 *   { message: string, kind: 'info' | 'success' | 'error', id: number }
 *
 * The `id` field is a freshly-stamped Date.now() per call \u2014 used as
 * a React key so that a new toast retriggers the fade-in animation
 * even when the previous toast is still on screen.
 *
 * Rendering null
 * ──────────────
 * Renders null when toast is null so the consumer can always include
 * <Toast toast={toast} onDismiss={dismissToast} /> in their JSX
 * without an outer conditional. Simpler caller, same DOM.
 */
export function Toast({ toast, onDismiss }) {
  if (!toast) return null;

  return (
    // Wrap exists so the inner pill can use a fade-in animation that
    // includes a horizontal translateX(-50%) for centering \u2014 if the
    // animation were on the pill itself, the centering math would
    // collide with the keyframe transforms. The wrap holds the
    // positioning, the pill holds the visual chrome.
    <div className="app-toast-wrap" key={toast.id}>
      <div
        className={`app-toast app-toast--${toast.kind}`}
        role="status"
        // 'polite' so screen readers announce the message after the
        // current utterance finishes \u2014 'assertive' would interrupt,
        // which is too aggressive for "link copied" type messages.
        aria-live="polite"
      >
        <span className="app-toast__message">{toast.message}</span>
        <button
          type="button"
          className="app-toast__close"
          onClick={onDismiss}
          aria-label={t('toast.dismiss')}
        >
          ✕
        </button>
      </div>
    </div>
  );
}
