/**
 * PWA Hook - React hook for Progressive Web App functionality
 * FE-TYPE-012: Fully typed hook return
 */

import { useState, useEffect } from 'react';
import { pwaService, type PWAStatus } from '@/services/pwa';
import { logger } from '@/utils/logger';
import type {
  UsePWAReturn,
  UsePWAInstallBannerReturn,
  UseOfflineDetectionReturn,
} from './types';

export function usePWA(): UsePWAReturn {
  const [status, setStatus] = useState<PWAStatus>(pwaService.getStatus());
  const [isInstalling, setIsInstalling] = useState(false);
  const [isUpdating, setIsUpdating] = useState(false);

  useEffect(() => {
    // Subscribe to PWA status changes
    const unsubscribe = pwaService.onStatusChange(setStatus);

    // Initial status check
    setStatus(pwaService.getStatus());

    return unsubscribe;
  }, []);

  /**
   * Install the PWA
   */
  const install = async (): Promise<boolean> => {
    if (!status.isInstallable || isInstalling) {
      return false;
    }

    setIsInstalling(true);

    try {
      const result = await pwaService.promptInstall();
      return result;
    } catch (error) {
      logger.error('[PWA Hook] Install failed', {
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined,
      });
      return false;
    } finally {
      setIsInstalling(false);
    }
  };

  /**
   * Update the service worker
   */
  const update = async (): Promise<void> => {
    if (!status.updateAvailable || isUpdating) {
      return;
    }

    setIsUpdating(true);

    try {
      await pwaService.updateServiceWorker();
    } catch (error) {
      logger.error('[PWA Hook] Update failed', {
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined,
      });
    } finally {
      setIsUpdating(false);
    }
  };

  /**
   * Request notification permission
   */
  const requestNotifications = async (): Promise<NotificationPermission> => {
    return await pwaService.requestNotificationPermission();
  };

  /**
   * Show a notification
   */
  const showNotification = async (
    title: string,
    options?: NotificationOptions,
  ): Promise<void> => {
    return await pwaService.showNotification(title, options);
  };

  /**
   * Clear all caches
   */
  const clearCaches = async (): Promise<void> => {
    return await pwaService.clearCaches();
  };

  /**
   * Get service worker version
   */
  const getVersion = async (): Promise<string> => {
    return await pwaService.getVersion();
  };

  return {
    // Status
    ...status,
    hasServiceWorker: status.serviceWorkerReady,

    // Loading states
    isInstalling,
    isUpdating,

    // Actions
    install,
    update,
    requestNotifications,
    showNotification,
    clearCaches,
    getVersion,

    // Computed properties
    canInstall: status.isInstallable && !isInstalling,
    canUpdate: status.updateAvailable && !isUpdating,
    isOffline: !status.isOnline,
  };
}

/**
 * Hook for PWA install banner
 * FE-TYPE-012: Fully typed hook return
 */
export function usePWAInstallBanner(): UsePWAInstallBannerReturn {
  const { isInstallable, isInstalled, install, isInstalling } = usePWA();
  const [showBanner, setShowBanner] = useState(false);
  const [dismissed, setDismissed] = useState(false);

  useEffect(() => {
    // Show banner if app is installable and not dismissed
    const shouldShow = isInstallable && !isInstalled && !dismissed;
    setShowBanner(shouldShow);
  }, [isInstallable, isInstalled, dismissed]);

  const handleInstall = async () => {
    const success = await install();
    if (success) {
      setShowBanner(false);
    }
  };

  const handleDismiss = () => {
    setDismissed(true);
    setShowBanner(false);

    // Remember dismissal for this session
    sessionStorage.setItem('pwa-install-dismissed', 'true');
  };

  // Check if banner was dismissed this session
  useEffect(() => {
    const wasDismissed =
      sessionStorage.getItem('pwa-install-dismissed') === 'true';
    setDismissed(wasDismissed);
  }, []);

  return {
    showBanner,
    isInstalling,
    handleInstall,
    handleDismiss,
  };
}

/**
 * Hook for offline detection and handling
 * FE-TYPE-012: Fully typed hook return
 */
export function useOfflineDetection(): UseOfflineDetectionReturn {
  const { isOnline } = usePWA();
  const [showOfflineBanner, setShowOfflineBanner] = useState(false);

  useEffect(() => {
    if (!isOnline) {
      setShowOfflineBanner(true);

      // Auto-hide after 5 seconds
      const timer = setTimeout(() => {
        setShowOfflineBanner(false);
      }, 5000);

      return () => clearTimeout(timer);
    }
    setShowOfflineBanner(false);
    return undefined;
  }, [isOnline]);

  return {
    isOnline,
    isOffline: !isOnline,
    showOfflineBanner,
    dismissOfflineBanner: () => setShowOfflineBanner(false),
  };
}
