import React, {
  createContext,
  useCallback,
  useContext,
  useRef,
  useState,
} from 'react';
import { Toast, ToastSeverity } from '@/types/notifications';
import { ToastContainer } from '@/Components/Toast';

// ── Context ──────────────────────────────────────────────────────────────────

interface NotificationContextValue {
  toasts: Toast[];
  /**
   * Show a transient toast for IMMEDIATE user feedback.
   *
   * Use for:
   *   - Successful user actions ("Order saved")
   *   - Transient non-actionable errors ("Cart is empty")
   *
   * Do NOT use for:
   *   - Payment lifecycle state → use PaymentStatusBanner
   *   - Field validation errors → use inline validation
   *   - Operational failures requiring action → use NotificationCenter
   */
  toast: (severity: ToastSeverity, title: string, message?: string, durationMs?: number) => void;
  dismissToast: (id: string) => void;
}

const NotificationContext = createContext<NotificationContextValue | null>(null);

// ── Provider ─────────────────────────────────────────────────────────────────

export function NotificationProvider({ children }: { children: React.ReactNode }) {
  const [toasts, setToasts] = useState<Toast[]>([]);
  const timers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});

  const dismissToast = useCallback((id: string) => {
    setToasts((prev) => prev.filter((t) => t.id !== id));
    clearTimeout(timers.current[id]);
    delete timers.current[id];
  }, []);

  const toast = useCallback(
    (severity: ToastSeverity, title: string, message?: string, durationMs = 4000) => {
      const id = crypto.randomUUID();
      const newToast: Toast = { id, severity, title, message, durationMs };

      setToasts((prev) => {
        // Limit to 5 toasts at once — drop oldest to avoid overwhelming the UI
        const capped = prev.length >= 5 ? prev.slice(1) : prev;
        return [...capped, newToast];
      });

      if (durationMs > 0) {
        timers.current[id] = setTimeout(() => dismissToast(id), durationMs);
      }
    },
    [dismissToast]
  );

  return (
    <NotificationContext.Provider value={{ toasts, toast, dismissToast }}>
      {children}
      {/* Toast container is rendered outside the page tree but inside the provider */}
      <ToastContainer toasts={toasts} onDismiss={dismissToast} />
    </NotificationContext.Provider>
  );
}

// ── Hook ─────────────────────────────────────────────────────────────────────

export function useNotification(): NotificationContextValue {
  const ctx = useContext(NotificationContext);
  if (!ctx) {
    throw new Error('useNotification must be used inside <NotificationProvider>');
  }
  return ctx;
}
