import { createContext, useContext, useState, useEffect, ReactNode } from 'react';

interface NotificationContextType {
  permission: NotificationPermission;
  isSubscribed: boolean;
  showNotification: (notification: any) => Promise<void>;
  requestPermission: () => Promise<NotificationPermission>;
}

interface NotificationData {
  title: string;
  body: string;
  icon?: string;
  badge?: string;
  tag?: string;
  requireInteraction?: boolean;
  silent?: boolean;
  data?: any;
}

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

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

interface NotificationProviderProps {
  children: ReactNode;
}

export const NotificationProvider: React.FC<NotificationProviderProps> = ({ children }) => {
  const [permission, setPermission] = useState<NotificationPermission>('default');
  const [isSubscribed, setIsSubscribed] = useState(false);
  const [isServiceWorkerSupported, setIsServiceWorkerSupported] = useState(false);

  useEffect(() => {
    // Check if we're in an iframe environment (like Figma Make)
    const isInIframe = window.self !== window.top || window.parent !== window;
    const isLocalhost = window.location.hostname === 'localhost';
    const isFigmaPreview = window.location.hostname.includes('figma');
    
    // Only attempt service worker registration in standalone environments
    const canUseServiceWorker = 'serviceWorker' in navigator && 
                               !isInIframe && 
                               !isFigmaPreview &&
                               window.location.protocol === 'https:';

    setIsServiceWorkerSupported(canUseServiceWorker);

    // Set initial notification permission if available
    if ('Notification' in window) {
      setPermission(Notification.permission);
    } else {
      // In environments without notification support, set to denied to avoid permission prompts
      setPermission('denied');
    }

    // Only try to initialize service worker in supported environments
    if (canUseServiceWorker) {
      // Small delay to avoid race conditions
      setTimeout(() => {
        initializeServiceWorker();
      }, 100);
    } else {
      // In iframe or unsupported environment, enable basic notification support
      setIsSubscribed(true); // Allow visual notifications
    }
  }, []);

  const initializeServiceWorker = async () => {
    try {
      // Check if service worker is already registered
      const existingRegistration = await navigator.serviceWorker.getRegistration();
      if (existingRegistration) {
        setIsSubscribed(true);
        return;
      }

      // Try to register service worker
      const registration = await navigator.serviceWorker.register('/sw.js', { 
        scope: '/' 
      });
      setIsSubscribed(true);
    } catch (error) {
      // Service worker registration failed, but we continue with visual notifications
      setIsSubscribed(true); // Still allow visual notifications
    }
  };

  const requestPermission = async (): Promise<NotificationPermission> => {
    // Don't request permission in iframe environments or if not supported
    if (!('Notification' in window) || window.self !== window.top) {
      return 'denied';
    }

    try {
      let result = Notification.permission;
      
      // Only request if permission is default and we're in a valid environment
      if (result === 'default') {
        // Check if we're in a secure context and not in an iframe
        if (window.isSecureContext && window.self === window.top) {
          result = await Notification.requestPermission();
        } else {
          // In insecure context or iframe, don't request permission
          result = 'denied';
        }
      }
      
      setPermission(result);
      return result;
    } catch (error) {
      // Permission request failed, continue with visual notifications
      setPermission('denied');
      return 'denied';
    }
  };

  const showNotification = async (notificationData: NotificationData): Promise<void> => {
    try {
      // Check if notifications are supported
      if (!('Notification' in window)) {
        console.log('Notifications not supported, showing fallback');
        showFallbackNotification(notificationData);
        return;
      }

      // Check permission
      if (permission !== 'granted') {
        console.log('Notification permission not granted');
        showFallbackNotification(notificationData);
        return;
      }

      // Try to show native notification
      try {
        const notification = new Notification(notificationData.title, {
          body: notificationData.body,
          icon: notificationData.icon || '/favicon.ico',
          badge: notificationData.badge || '/favicon.ico',
          tag: notificationData.tag || 'enamel-notification',
          requireInteraction: notificationData.requireInteraction || false,
          silent: notificationData.silent || false,
          data: notificationData.data
        });

        // Auto-close after 5 seconds if not requiring interaction
        if (!notificationData.requireInteraction) {
          setTimeout(() => {
            notification.close();
          }, 5000);
        }

        console.log('Native notification shown successfully');
      } catch (notificationError) {
        console.log('Native notification failed, using fallback:', notificationError);
        showFallbackNotification(notificationData);
      }
    } catch (error) {
      console.log('Notification system error, using fallback:', error);
      showFallbackNotification(notificationData);
    }
  };

  const showFallbackNotification = (notificationData: NotificationData) => {
    // Create a visual notification that appears in the UI
    const notification = document.createElement('div');
    notification.className = 'fixed top-4 right-4 bg-card border border-border rounded-lg p-4 shadow-lg z-50 max-w-sm animate-in slide-in-from-right duration-300';
    notification.innerHTML = `
      <div class="flex items-start gap-3">
        <div class="flex-shrink-0">
          <div class="w-8 h-8 bg-primary rounded-full flex items-center justify-center">
            <span class="text-white text-sm font-bold">E</span>
          </div>
        </div>
        <div class="flex-1 min-w-0">
          <h4 class="text-sm font-medium text-foreground">${notificationData.title}</h4>
          <p class="text-sm text-muted-foreground mt-1">${notificationData.body}</p>
        </div>
        <button class="flex-shrink-0 text-muted-foreground hover:text-foreground" onclick="this.parentElement.parentElement.remove()">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
          </svg>
        </button>
      </div>
    `;

    document.body.appendChild(notification);

    // Auto-remove after 5 seconds
    setTimeout(() => {
      if (notification.parentElement) {
        notification.style.animation = 'slide-out-to-right 300ms ease-in forwards';
        setTimeout(() => {
          if (notification.parentElement) {
            notification.remove();
          }
        }, 300);
      }
    }, 5000);

    console.log('Fallback notification displayed');
  };

  const value: NotificationContextType = {
    permission,
    isSubscribed: isSubscribed || isServiceWorkerSupported, // Consider it "subscribed" if we can show notifications
    showNotification,
    requestPermission
  };

  return (
    <NotificationContext.Provider value={value}>
      {children}
    </NotificationContext.Provider>
  );
};