/**
 * InstallPromptStore
 *
 * Story 3.4: Zustand store for PWA install prompt state management
 *
 * Architecture Compliance:
 * - Uses atomic selectors pattern to prevent unnecessary re-renders
 * - Stores the beforeinstallprompt event for later triggering
 * - Tracks installability and installed status
 */

import { create } from 'zustand';

/**
 * BeforeInstallPromptEvent interface
 *
 * Extension of the standard Event with PWA-specific properties
 */
export interface BeforeInstallPromptEvent extends Event {
  prompt: () => Promise<void>;
  userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
}

/**
 * Install prompt state interface
 */
interface InstallPromptState {
  isInstallable: boolean;
  isInstalled: boolean;
  deferredPrompt: BeforeInstallPromptEvent | null;

  // Actions
  setDeferredPrompt: (event: BeforeInstallPromptEvent | null) => void;
  setInstallable: (installable: boolean) => void;
  setInstalled: (installed: boolean) => void;
  promptInstall: () => Promise<boolean>;
  dismissInstall: () => void;
}

/**
 * Install prompt store
 *
 * Manages the PWA install prompt state.
 * Stores the beforeinstallprompt event for custom UI triggering.
 */
export const useInstallPromptStore = create<InstallPromptState>((set, get) => ({
  // Initial state
  isInstallable: false,
  isInstalled: false,
  deferredPrompt: null,

  /**
   * Set the deferred prompt event
   * Also updates isInstallable based on event presence
   */
  setDeferredPrompt: (event: BeforeInstallPromptEvent | null) => {
    set({ deferredPrompt: event, isInstallable: !!event });
  },

  /**
   * Set installable status directly
   * Used for manual control or testing
   */
  setInstallable: (installable: boolean) => {
    set({ isInstallable: installable });
  },

  /**
   * Set installed status
   * When true, the app is running in standalone mode
   */
  setInstalled: (installed: boolean) => {
    set({ isInstalled: installed });
  },

  /**
   * Trigger the install prompt
   * Calls the stored event's prompt() method
   * @returns true if user accepted, false if dismissed
   */
  promptInstall: async () => {
    const { deferredPrompt } = get();

    if (!deferredPrompt) {
      return false;
    }

    // Show the browser's install prompt
    deferredPrompt.prompt();

    // Wait for user's choice
    const { outcome } = await deferredPrompt.userChoice;

    if (outcome === 'accepted') {
      // User accepted - mark as installed and clear prompt
      set({
        isInstalled: true,
        deferredPrompt: null,
        isInstallable: false
      });
    } else {
      // User dismissed - just clear the prompt
      set({
        deferredPrompt: null,
        isInstallable: false
      });
    }

    return outcome === 'accepted';
  },

  /**
   * Dismiss the install prompt
   * Clears the stored event without triggering the prompt
   */
  dismissInstall: () => {
    set({
      deferredPrompt: null,
      isInstallable: false
    });
  }
}));
