import { useState, useEffect, useCallback } from 'react';
import { serviceWorkerManager, isOffline, isInIframe } from '../utils/serviceWorker';

export interface UseServiceWorkerReturn {
  isSupported: boolean;
  isRegistered: boolean;
  isOffline: boolean;
  isInIframe: boolean;
  cacheSize: number;
  loading: boolean;
  error: string | null;
  updateServiceWorker: () => Promise<void>;
  clearCache: () => Promise<void>;
  getCacheSize: () => Promise<void>;
  preloadAssets: (urls: string[]) => Promise<void>;
}

export const useServiceWorker = (): UseServiceWorkerReturn => {
  const [isSupported, setIsSupported] = useState(false);
  const [isRegistered, setIsRegistered] = useState(serviceWorkerManager.isRegistered);
  const [cacheSize, setCacheSize] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [offline, setOffline] = useState(isOffline());

  // Check service worker support dynamically, especially for iframes
  useEffect(() => {
    const checkSupport = async () => {
      try {
        // Basic check for service worker API
        if (!('serviceWorker' in navigator)) {
          console.warn('[SW Hook] Service Worker API not available');
          setIsSupported(false);
          return;
        }

        // Additional iframe-specific checks
        const inIframe = isInIframe();
        if (inIframe) {
          console.log('[SW Hook] Running in iframe, performing additional checks...');
          
          // Check if we can access the service worker in iframe context
          try {
            // Try to access navigator.serviceWorker properties
            // Just accessing these properties will throw if restricted
            void navigator.serviceWorker.controller;
            void navigator.serviceWorker.ready;
            
            // If we can access these without throwing, we're likely supported
            setIsSupported(true);
            console.log('[SW Hook] Service Worker supported in iframe context');
          } catch (iframeError) {
            console.warn('[SW Hook] Service Worker restricted in iframe:', iframeError);
            setIsSupported(false);
            return;
          }
        } else {
          // Not in iframe, standard check should suffice
          setIsSupported(true);
        }

        // Try to check if we can actually register (more thorough check)
        try {
          const registrations = await navigator.serviceWorker.getRegistrations();
          console.log('[SW Hook] Service Worker fully supported, existing registrations:', registrations.length);
        } catch (regError) {
          console.warn('[SW Hook] Service Worker getRegistrations failed:', regError);
          // Still might be supported, just restricted
        }

      } catch (error) {
        console.error('[SW Hook] Error checking service worker support:', error);
        setIsSupported(false);
      }
    };

    checkSupport();
  }, []);

  // Update registration status
  useEffect(() => {
    if (!isSupported) return;

    const checkRegistration = () => {
      setIsRegistered(serviceWorkerManager.isRegistered);
    };

    // Check periodically
    const interval = setInterval(checkRegistration, 1000);
    checkRegistration();

    return () => clearInterval(interval);
  }, [isSupported]);

  // Update cache size periodically
  useEffect(() => {
    const updateCacheSize = async () => {
      if (serviceWorkerManager.isRegistered) {
        try {
          const size = await serviceWorkerManager.getCacheSize();
          setCacheSize(size);
        } catch (err) {
          console.error('Failed to get cache size:', err);
        }
      }
    };

    updateCacheSize();
    const interval = setInterval(updateCacheSize, 30000); // Update every 30 seconds

    return () => clearInterval(interval);
  }, [isRegistered]);

  // Listen for online/offline events
  useEffect(() => {
    const handleOnline = () => setOffline(false);
    const handleOffline = () => setOffline(true);

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  const updateServiceWorker = useCallback(async () => {
    setLoading(true);
    setError(null);
    
    try {
      await serviceWorkerManager.update();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to update service worker');
    } finally {
      setLoading(false);
    }
  }, []);

  const clearCache = useCallback(async () => {
    setLoading(true);
    setError(null);
    
    try {
      await serviceWorkerManager.clearCache();
      setCacheSize(0);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to clear cache');
    } finally {
      setLoading(false);
    }
  }, []);

  const getCacheSize = useCallback(async () => {
    setLoading(true);
    setError(null);
    
    try {
      const size = await serviceWorkerManager.getCacheSize();
      setCacheSize(size);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to get cache size');
    } finally {
      setLoading(false);
    }
  }, []);

  const preloadAssets = useCallback(async (urls: string[]) => {
    setLoading(true);
    setError(null);
    
    try {
      await serviceWorkerManager.cacheUrls(urls);
      // Refresh cache size after preloading
      const size = await serviceWorkerManager.getCacheSize();
      setCacheSize(size);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to preload assets');
    } finally {
      setLoading(false);
    }
  }, []);

  return {
    isSupported,
    isRegistered,
    isOffline: offline,
    isInIframe: isInIframe(),
    cacheSize,
    loading,
    error,
    updateServiceWorker,
    clearCache,
    getCacheSize,
    preloadAssets,
  };
};
