import React, { createContext, useContext, useState, useRef, ReactNode, useCallback } from 'react';
import { Snackbar, Alert, AlertColor } from '@mui/material';

interface Notification {
  id: number;
  message: string;
  severity: AlertColor;
}

interface NotificationContextType {
  showSuccess: (message: string) => void;
  showError: (message: string) => void;
  showWarning: (message: string) => void;
  showInfo: (message: string) => void;
  showNotificationToast: (message: string, severity?: AlertColor) => void;
}

const NotificationContext = createContext<NotificationContextType | undefined>(undefined);

interface NotificationProviderProps {
  children: ReactNode;
}

export const NotificationProvider: React.FC<NotificationProviderProps> = ({ children }) => {
  const [currentNotification, setCurrentNotification] = useState<Notification | null>(null);
  const queueRef = useRef<Notification[]>([]);

  // Left-side toast queue for new backend notifications
  const [toastQueue, setToastQueue] = useState<Notification[]>([]);

  const addNotification = useCallback((message: string, severity: AlertColor) => {
    const id = Date.now();
    const notification: Notification = { id, message, severity };

    // Use functional update to avoid stale closure over currentNotification
    setCurrentNotification((prev) => {
      if (prev) {
        queueRef.current.push(notification);
        return prev;
      }
      return notification;
    });
  }, []);

  const showSuccess = useCallback((message: string) => {
    addNotification(message, 'success');
  }, [addNotification]);

  const showError = useCallback((message: string) => {
    addNotification(message, 'error');
  }, [addNotification]);

  const showWarning = useCallback((message: string) => {
    addNotification(message, 'warning');
  }, [addNotification]);

  const showInfo = useCallback((message: string) => {
    addNotification(message, 'info');
  }, [addNotification]);

  const showNotificationToast = useCallback((message: string, severity: AlertColor = 'info') => {
    const id = Date.now() + Math.random();
    setToastQueue((prev) => [...prev, { id, message, severity }]);
  }, []);

  const handleClose = (_event?: React.SyntheticEvent | Event, reason?: string) => {
    if (reason === 'clickaway') {
      return;
    }

    setCurrentNotification(null);

    // Show next queued notification after a short delay
    setTimeout(() => {
      const next = queueRef.current.shift();
      if (next) {
        setCurrentNotification(next);
      }
    }, 200);
  };

  const handleToastClose = (_event?: React.SyntheticEvent | Event, reason?: string) => {
    if (reason === 'clickaway') return;
    setToastQueue((prev) => prev.slice(1));
  };

  const value: NotificationContextType = {
    showSuccess,
    showError,
    showWarning,
    showInfo,
    showNotificationToast,
  };

  return (
    <NotificationContext.Provider value={value}>
      {children}
      {/* Right-side: action feedback */}
      <Snackbar
        open={currentNotification !== null}
        autoHideDuration={6000}
        onClose={handleClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
      >
        <Alert
          onClose={handleClose}
          severity={currentNotification?.severity || 'info'}
          variant="filled"
          sx={{ width: '100%' }}
        >
          {currentNotification?.message}
        </Alert>
      </Snackbar>
      {/* Left-side: new backend notification toasts */}
      <Snackbar
        open={toastQueue.length > 0}
        autoHideDuration={5000}
        onClose={handleToastClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
      >
        <Alert
          onClose={handleToastClose}
          severity={toastQueue[0]?.severity || 'info'}
          variant="filled"
          sx={{ width: '100%' }}
        >
          {toastQueue[0]?.message}
        </Alert>
      </Snackbar>
    </NotificationContext.Provider>
  );
};

export const useNotification = (): NotificationContextType => {
  const context = useContext(NotificationContext);
  if (context === undefined) {
    throw new Error('useNotification must be used within a NotificationProvider');
  }
  return context;
};
