/**
 * Device state collector — memory, battery, storage, network
 *
 * @module device
 */

import type { DeviceState } from './types.js';

// DOM type declarations for ESLint
type Navigator = {
  onLine: boolean;
  connection?: { effectiveType?: string };
  getBattery?: () => Promise<{ charging: boolean; level: number }>;
  storage?: { estimate(): Promise<{ usage?: number }> };
};
declare const navigator: Navigator;
declare const performance: { memory?: { usedJSHeapSize: number } };
interface Window {
  addEventListener: (type: string, listener: () => void) => void;
  removeEventListener: (type: string, listener: () => void) => void;
}
declare const window: Window;

/**
 * Collect current device state
 * Best-effort: some APIs may not be available in all environments
 */
export function collectDeviceState(): DeviceState {
  const state: DeviceState = {
    isOnline: navigator.onLine ?? true,
  };

  // Network type (experimental API)
  const connection = (navigator as { connection?: { effectiveType?: string } }).connection;
  if (connection) {
    state.networkType = connection.effectiveType ?? 'unknown';
  }

  // Battery API (experimental, not widely supported)
  // Note: Battery API is deprecated but still useful for diagnostics
  const battery = (
    navigator as { getBattery?: () => Promise<{ charging: boolean; level: number }> }
  ).getBattery;
  if (battery) {
    // We'll return a promise, but sync API can't wait
    // Store last known value if available
  }

  // Memory (Chrome-only experimental)
  const memory = (performance as { memory?: { usedJSHeapSize: number } }).memory;
  if (memory) {
    state.memoryMB = Math.round(memory.usedJSHeapSize / 1024 / 1024);
  }

  // Storage (async, but we'll fire-and-forget)
  if (navigator.storage && navigator.storage.estimate) {
    navigator.storage
      .estimate()
      .then(estimate => {
        if (estimate.usage !== undefined) {
          state.storageMB = Math.round(estimate.usage / 1024 / 1024);
        }
      })
      .catch(() => {
        // Ignore errors
      });
  }

  return state;
}

/**
 * Subscribe to online/offline events
 */
export function subscribeToConnectivity(callback: (isOnline: boolean) => void): () => void {
  const handleOnline = () => callback(true);
  const handleOffline = () => callback(false);

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

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