/**
 * Device data collected from browser navigator APIs.
 * This data is sent to the backend to enrich analytics.
 */
export interface CollectedDeviceData {
  screenWidth: number;
  screenHeight: number;
  viewportWidth: number;
  viewportHeight: number;
  language: string;
  languages: readonly string[];
  timezone: string;
  timezoneOffset: number;
  platform: string;
  deviceMemory: number | undefined;
  hardwareConcurrency: number | undefined;
  colorDepth: number;
  pixelRatio: number;
  touchPoints: number;
  cookiesEnabled: boolean;
  doNotTrack: string | null;
  onLine: boolean;
}

/**
 * Extended Navigator interface with optional properties
 * that aren't in all browser implementations.
 */
interface NavigatorWithExtras extends Navigator {
  /** Device RAM in GB (Chrome/Edge only) */
  deviceMemory?: number;
  /** Network connection info */
  connection?: {
    saveData: boolean;
    effectiveType?: string;
  };
}

/**
 * Collect device data from browser navigator APIs.
 * Returns null if running in a non-browser environment (SSR).
 *
 * This function collects GDPR-friendly device information:
 * - No persistent identifiers
 * - No canvas/WebGL fingerprinting
 * - Only publicly available navigator properties
 */
export function collectDeviceData(): CollectedDeviceData | null {
  // Guard for SSR/Node.js environments
  if (typeof window === 'undefined' || typeof navigator === 'undefined') {
    return null;
  }

  const nav = navigator as NavigatorWithExtras;

  return {
    // Screen dimensions (physical display)
    screenWidth: window.screen.width,
    screenHeight: window.screen.height,

    // Viewport dimensions (browser window content area)
    viewportWidth: window.innerWidth,
    viewportHeight: window.innerHeight,

    // Locale information
    language: navigator.language,
    languages: navigator.languages,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    timezoneOffset: new Date().getTimezoneOffset(),

    // Platform (deprecated but still useful)
    platform: navigator.platform,

    // Device capabilities
    deviceMemory: nav.deviceMemory,
    hardwareConcurrency: navigator.hardwareConcurrency,
    colorDepth: window.screen.colorDepth,
    pixelRatio: window.devicePixelRatio,
    touchPoints: navigator.maxTouchPoints,

    // Privacy/capability flags
    cookiesEnabled: navigator.cookieEnabled,
    doNotTrack: navigator.doNotTrack,
    onLine: navigator.onLine,
  };
}

// ─────────────────────────────────────────────────────────────────────────────
// Memoized Version
// ─────────────────────────────────────────────────────────────────────────────

let cachedData: CollectedDeviceData | null = null;
let cacheInitialized = false;

/**
 * Get device data with memoization.
 * The data is collected once per session and cached.
 *
 * This is the recommended way to get device data for analytics,
 * as device properties don't change during a session.
 */
export function getDeviceData(): CollectedDeviceData | null {
  if (!cacheInitialized) {
    cachedData = collectDeviceData();
    cacheInitialized = true;
  }
  return cachedData;
}

/**
 * Reset the device data cache.
 * Useful for testing or when session changes.
 */
export function resetDeviceDataCache(): void {
  cachedData = null;
  cacheInitialized = false;
}

/**
 * Get current viewport dimensions.
 * Unlike getDeviceData(), this always returns fresh values.
 * Use this for resize tracking.
 */
export function getViewportSize(): { width: number; height: number } | null {
  if (typeof window === 'undefined') {
    return null;
  }

  return {
    width: window.innerWidth,
    height: window.innerHeight,
  };
}
