import React from 'react';
import {
  BeforeInstallPromptEvent,
  getStandaloneStatus,
  isIosDevice,
  type InstallOutcome,
} from '../lib/installPrompt';

type InstallPromptState = {
  canInstall: boolean;
  isInstalled: boolean;
  isStandalone: boolean;
  isIos: boolean;
  outcome: InstallOutcome | null;
  promptInstall: () => Promise<InstallOutcome | null>;
};

export function useInstallPrompt(): InstallPromptState {
  const [deferredPrompt, setDeferredPrompt] = React.useState<BeforeInstallPromptEvent | null>(null);
  const [isInstalled, setIsInstalled] = React.useState(false);
  const [isStandalone, setIsStandalone] = React.useState(false);
  const [isIos, setIsIos] = React.useState(false);
  const [outcome, setOutcome] = React.useState<InstallOutcome | null>(null);

  React.useEffect(() => {
    if (typeof window === 'undefined') {
      return undefined;
    }

    const updateStandalone = () => {
      const standalone = getStandaloneStatus();
      setIsStandalone(standalone);
      if (standalone) {
        setIsInstalled(true);
      }
    };

    setIsIos(isIosDevice(navigator.userAgent ?? ''));
    updateStandalone();

    const handleBeforeInstallPrompt = (event: Event) => {
      event.preventDefault();
      setDeferredPrompt(event as BeforeInstallPromptEvent);
    };

    const handleAppInstalled = () => {
      setIsInstalled(true);
      setDeferredPrompt(null);
      setOutcome('accepted');
    };

    const mediaQuery = window.matchMedia?.('(display-mode: standalone)');
    const handleDisplayModeChange = () => updateStandalone();

    window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
    window.addEventListener('appinstalled', handleAppInstalled);
    mediaQuery?.addEventListener?.('change', handleDisplayModeChange);

    return () => {
      window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
      window.removeEventListener('appinstalled', handleAppInstalled);
      mediaQuery?.removeEventListener?.('change', handleDisplayModeChange);
    };
  }, []);

  const promptInstall = React.useCallback(async () => {
    if (!deferredPrompt) {
      return null;
    }

    await deferredPrompt.prompt();
    const choice = await deferredPrompt.userChoice;
    setOutcome(choice.outcome ?? 'unknown');

    if (choice.outcome === 'accepted') {
      setIsInstalled(true);
      setDeferredPrompt(null);
    }

    return choice.outcome ?? 'unknown';
  }, [deferredPrompt]);

  return {
    canInstall: Boolean(deferredPrompt),
    isInstalled,
    isStandalone,
    isIos,
    outcome,
    promptInstall,
  };
}
