/**
 * Device Fingerprinting - Datenschutzkonform
 *
 * Generiert einen anonymen Fingerprint OHNE:
 * - Canvas Fingerprinting
 * - WebGL Fingerprinting
 * - Audio Fingerprinting
 * - Hardware-spezifische IDs
 *
 * Verwendet nur:
 * - User Agent
 * - Sprache
 * - Bildschirmaufloesung
 * - Zeitzone
 * - Platform
 */

/**
 * Fingerprint-Komponenten sammeln
 */
function getComponents(): string[] {
  if (typeof window === 'undefined') {
    return ['server'];
  }

  const components: string[] = [];

  // User Agent (anonymisiert)
  try {
    // Nur Browser-Familie, nicht vollstaendiger UA
    const ua = navigator.userAgent;
    if (ua.includes('Chrome')) components.push('chrome');
    else if (ua.includes('Firefox')) components.push('firefox');
    else if (ua.includes('Safari')) components.push('safari');
    else if (ua.includes('Edge')) components.push('edge');
    else components.push('other');
  } catch {
    components.push('unknown-browser');
  }

  // Sprache
  try {
    components.push(navigator.language || 'unknown-lang');
  } catch {
    components.push('unknown-lang');
  }

  // Bildschirm-Kategorie (nicht exakte Aufloesung)
  try {
    const width = window.screen.width;
    if (width >= 2560) components.push('4k');
    else if (width >= 1920) components.push('fhd');
    else if (width >= 1366) components.push('hd');
    else if (width >= 768) components.push('tablet');
    else components.push('mobile');
  } catch {
    components.push('unknown-screen');
  }

  // Farbtiefe (grob)
  try {
    const depth = window.screen.colorDepth;
    if (depth >= 24) components.push('deep-color');
    else components.push('standard-color');
  } catch {
    components.push('unknown-color');
  }

  // Zeitzone (nur Offset, nicht Name)
  try {
    const offset = new Date().getTimezoneOffset();
    const hours = Math.floor(Math.abs(offset) / 60);
    const sign = offset <= 0 ? '+' : '-';
    components.push(`tz${sign}${hours}`);
  } catch {
    components.push('unknown-tz');
  }

  // Platform-Kategorie
  try {
    const platform = navigator.platform?.toLowerCase() || '';
    if (platform.includes('mac')) components.push('mac');
    else if (platform.includes('win')) components.push('win');
    else if (platform.includes('linux')) components.push('linux');
    else if (platform.includes('iphone') || platform.includes('ipad'))
      components.push('ios');
    else if (platform.includes('android')) components.push('android');
    else components.push('other-platform');
  } catch {
    components.push('unknown-platform');
  }

  // Touch-Faehigkeit
  try {
    if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
      components.push('touch');
    } else {
      components.push('no-touch');
    }
  } catch {
    components.push('unknown-touch');
  }

  // Do Not Track (als Datenschutz-Signal)
  try {
    if (navigator.doNotTrack === '1') {
      components.push('dnt');
    }
  } catch {
    // Ignorieren
  }

  return components;
}

/**
 * SHA-256 Hash (async, nutzt SubtleCrypto)
 */
async function sha256(message: string): Promise<string> {
  if (typeof window === 'undefined' || !window.crypto?.subtle) {
    // Fallback fuer Server/alte Browser
    return simpleHash(message);
  }

  try {
    const encoder = new TextEncoder();
    const data = encoder.encode(message);
    const hashBuffer = await crypto.subtle.digest('SHA-256', data);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
  } catch {
    return simpleHash(message);
  }
}

/**
 * Fallback Hash-Funktion (djb2)
 */
function simpleHash(str: string): string {
  let hash = 5381;
  for (let i = 0; i < str.length; i++) {
    hash = (hash * 33) ^ str.charCodeAt(i);
  }
  return (hash >>> 0).toString(16).padStart(8, '0');
}

/**
 * Datenschutzkonformen Fingerprint generieren
 *
 * Der Fingerprint ist:
 * - Nicht eindeutig (viele Nutzer teilen sich denselben)
 * - Nicht persistent (aendert sich bei Browser-Updates)
 * - Nicht invasiv (keine Canvas/WebGL/Audio)
 * - Anonymisiert (SHA-256 Hash)
 */
export async function generateFingerprint(): Promise<string> {
  const components = getComponents();
  const combined = components.join('|');
  const hash = await sha256(combined);

  // Prefix fuer Identifikation
  return `fp_${hash.substring(0, 32)}`;
}

/**
 * Synchrone Version (mit einfachem Hash)
 */
export function generateFingerprintSync(): string {
  const components = getComponents();
  const combined = components.join('|');
  const hash = simpleHash(combined);

  return `fp_${hash}`;
}

export default generateFingerprint;
