/**
 * PWA Types and Interfaces
 * 
 * Type definitions for Progressive Web App configuration
 * Extracted from Holy Habit PWA implementation
 */

// Manifest.json related types
export interface PWAIcon {
  src: string;
  sizes: string;
  type: string;
  purpose?: 'any' | 'maskable' | 'monochrome' | 'any maskable';
}

export interface PWAShortcut {
  name: string;
  short_name?: string;
  description?: string;
  url: string;
  icons?: PWAIcon[];
}

export interface PWAScreenshot {
  src: string;
  sizes: string;
  type: string;
  label?: string;
  platform?: 'wide' | 'narrow';
}

export interface PWAFileHandler {
  action: string;
  accept: Record<string, string[]>;
}

export interface PWAProtocolHandler {
  protocol: string;
  url: string;
}

export interface PWAEdgeSidePanel {
  preferred_width?: number;
}

export interface PWAManifest {
  name: string;
  short_name: string;
  description: string;
  start_url: string;
  display: 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser';
  background_color: string;
  theme_color: string;
  orientation?: 'any' | 'natural' | 'landscape' | 'landscape-primary' | 'landscape-secondary' | 'portrait' | 'portrait-primary' | 'portrait-secondary';
  scope?: string;
  lang?: string;
  icons: PWAIcon[];
  shortcuts?: PWAShortcut[];
  categories?: string[];
  iarc_rating_id?: string;
  edge_side_panel?: PWAEdgeSidePanel;
  file_handlers?: PWAFileHandler[];
  protocol_handlers?: PWAProtocolHandler[];
  screenshots?: PWAScreenshot[];
  related_applications?: any[];
  prefer_related_applications?: boolean;
}

// Service Worker related types
export interface ServiceWorkerConfig {
  cacheName: string;
  version: string;
  urlsToCache: string[];
  networkFirst?: string[];
  cacheFirst?: string[];
  staleWhileRevalidate?: string[];
  cacheOnly?: string[];
  networkOnly?: string[];
  offlinePageUrl?: string;
  enableBackgroundSync?: boolean;
  enablePushNotifications?: boolean;
  skipWaiting?: boolean;
  clientsClaim?: boolean;
}

export interface CacheStrategy {
  name: 'networkFirst' | 'cacheFirst' | 'staleWhileRevalidate' | 'cacheOnly' | 'networkOnly';
  patterns: string[];
  options?: {
    cacheName?: string;
    expiration?: {
      maxEntries?: number;
      maxAgeSeconds?: number;
    };
  };
}

export interface PWANotificationOptions {
  body?: string;
  icon?: string;
  badge?: string;
  vibrate?: number[];
  tag?: string;
  renotify?: boolean;
  requireInteraction?: boolean;
  actions?: NotificationAction[];
}

export interface NotificationAction {
  action: string;
  title: string;
  icon?: string;
}

// PWA Configuration
export interface PWAConfig {
  name: string;
  shortName: string;
  description: string;
  themeColor: string;
  backgroundColor: string;
  startUrl?: string;
  scope?: string;
  display?: PWAManifest['display'];
  orientation?: PWAManifest['orientation'];
  lang?: string;
  categories?: string[];
  icons: {
    sizes: number[];
    basePath: string;
  };
  shortcuts?: Omit<PWAShortcut, 'icons'>[];
  screenshots?: Omit<PWAScreenshot, 'src'>[];
  serviceWorker?: ServiceWorkerConfig;
  offlineSupport?: boolean;
  pushNotifications?: boolean;
  backgroundSync?: boolean;
}

// Installation and lifecycle
export interface PWAInstallationState {
  isInstallable: boolean;
  isInstalled: boolean;
  installPrompt?: any; // BeforeInstallPromptEvent
  userChoice?: 'accepted' | 'dismissed';
}

export interface PWALifecycleEvents {
  onInstall?: () => void;
  onActivate?: () => void;
  onUpdateAvailable?: (newVersion: string) => void;
  onUpdateApplied?: () => void;
  onOffline?: () => void;
  onOnline?: () => void;
}

// Utility types
export interface PWACapabilities {
  serviceWorker: boolean;
  pushNotifications: boolean;
  backgroundSync: boolean;
  indexedDB: boolean;
  webShare: boolean;
  installPrompt: boolean;
  standalone: boolean;
}

export interface PWAMetrics {
  cacheHitRate: number;
  offlineUsage: number;
  installationRate: number;
  updateApplyRate: number;
  pushNotificationEngagement: number;
}

// Error types
export class PWAError extends Error {
  constructor(
    message: string,
    public code: 'MANIFEST_INVALID' | 'SERVICE_WORKER_FAILED' | 'CACHE_ERROR' | 'NOTIFICATION_DENIED' | 'INSTALL_FAILED',
    public details?: any
  ) {
    super(message);
    this.name = 'PWAError';
  }
}

export class ManifestError extends PWAError {
  constructor(message: string, details?: any) {
    super(message, 'MANIFEST_INVALID', details);
    this.name = 'ManifestError';
  }
}

export class ServiceWorkerError extends PWAError {
  constructor(message: string, details?: any) {
    super(message, 'SERVICE_WORKER_FAILED', details);
    this.name = 'ServiceWorkerError';
  }
}

export class CacheError extends PWAError {
  constructor(message: string, details?: any) {
    super(message, 'CACHE_ERROR', details);
    this.name = 'CacheError';
  }
}