// Clipboard API Interceptor
// Runs in page context to intercept all clipboard manipulation attempts
// Prevents malicious JavaScript from injecting commands into clipboard

(function() {
  'use strict';

  console.log('[PhishProtect] Clipboard interceptor initializing...');

  // Store original clipboard APIs
  const originalWriteText = navigator.clipboard?.writeText;
  const originalWrite = navigator.clipboard?.write;
  const originalReadText = navigator.clipboard?.readText;
  const originalRead = navigator.clipboard?.read;
  const originalExecCommand = document.execCommand;
  const originalAddEventListener = EventTarget.prototype.addEventListener;

  // ── Behavioral event-state for the v3 clipboard-poisoning ruleset ──────────
  // We already wrap the clipboard APIs to BLOCK command injection synchronously.
  // Here we ALSO record typed event-state (writes / copies / reads + permission)
  // and emit it (debounced) so the background can run dt-clipboard-poisoning-v3
  // — crypto-address swap, pastejacking, sensitive-data writes — report-only.
  // One sensor, two consumers: no second wrapper on the same APIs.
  const CLIP_MAX = 30;
  const clipState = {
    clipboardWrites: [],   // [{ originalText, newText }]
    copyEvents: [],        // [{ userSelected, pageModified }]
    clipboardReadCount: 0,
    // Biased toward "granted" — the unauthorized-write signal is weak and would
    // FP on every legit button-triggered copy; only an explicit denial flips it.
    permissions: { hasClipboardPermission: true },
  };
  let clipEmitTimer = null;
  function clipEmit() {
    try {
      window.postMessage({
        type: 'nithic-clipboard-state',
        state: {
          clipboardWrites: clipState.clipboardWrites.slice(-CLIP_MAX),
          copyEvents: clipState.copyEvents.slice(-CLIP_MAX),
          clipboardReadCount: clipState.clipboardReadCount,
          permissions: clipState.permissions,
        },
        url: location.href,
        timestamp: Date.now(),
      }, '*');
    } catch (_) { /* ignore */ }
  }
  function clipScheduleEmit() {
    if (clipEmitTimer) return;            // coalesce a burst into one post
    clipEmitTimer = setTimeout(() => { clipEmitTimer = null; clipEmit(); }, 500);
  }
  function recordWrite(originalText, newText) {
    if (typeof newText !== 'string' || !newText) return;
    clipState.clipboardWrites.push({
      originalText: typeof originalText === 'string' ? originalText.slice(0, 500) : '',
      newText: newText.slice(0, 500),
    });
    if (clipState.clipboardWrites.length > CLIP_MAX) clipState.clipboardWrites.shift();
    clipScheduleEmit();
  }
  function recordCopy(userSelected, pageModified) {
    const u = typeof userSelected === 'string' ? userSelected : '';
    const p = typeof pageModified === 'string' ? pageModified : '';
    if (!u && !p) return;
    clipState.copyEvents.push({ userSelected: u.slice(0, 500), pageModified: p.slice(0, 500) });
    if (clipState.copyEvents.length > CLIP_MAX) clipState.copyEvents.shift();
    // A copy whose clipboard content differs from the user's selection also
    // feeds crypto-swap (originalText vs newText, same-type addresses).
    if (u && p && u !== p) recordWrite(u, p);
    clipScheduleEmit();
  }
  // Best-effort clipboard-write permission (only an explicit "denied" matters).
  try {
    if (navigator.permissions?.query) {
      navigator.permissions.query({ name: 'clipboard-write' }).then((s) => {
        clipState.permissions.hasClipboardPermission = s.state !== 'denied';
        try { s.onchange = () => { clipState.permissions.hasClipboardPermission = s.state !== 'denied'; }; } catch (_) {}
      }).catch(() => {});
    }
  } catch (_) {}

  /**
   * Comprehensive command pattern detection
   * Matches the detector logic for consistency
   */
  function analyzeClipboardContent(text) {
    if (!text || typeof text !== 'string') {
      return { safe: true };
    }

    const threats = [];

    // PowerShell patterns (CRITICAL)
    const powershellPatterns = [
      {
        pattern: /powershell(?:\.exe)?.*?(?:Invoke-WebRequest|iwr|wget|curl).*?http/i,
        type: 'PowerShell HTTP Download',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:Invoke-Expression|iex)/i,
        type: 'PowerShell Invoke-Expression',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:Start-Process|start).*?(?:%temp%|%appdata%|http)/i,
        type: 'PowerShell Process Start',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?-enc(?:odedcommand)?.*?[A-Za-z0-9+\/=]{20,}/i,
        type: 'PowerShell Encoded Command',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:-w(?:indowstyle)?\s+hidden|-nop|-ep\s+bypass)/i,
        type: 'PowerShell Hidden/Bypass',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:DownloadString|DownloadFile)/i,
        type: 'PowerShell Download Method',
        severity: 'critical'
      },
      {
        pattern: /powershell(?:\.exe)?.*?Add-MpPreference.*?-ExclusionPath/i,
        type: 'PowerShell Disable Defender',
        severity: 'critical'
      }
    ];

    // CMD/Batch patterns (CRITICAL)
    const cmdPatterns = [
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?(?:curl|certutil|bitsadmin).*?http/i,
        type: 'CMD HTTP Download',
        severity: 'critical'
      },
      {
        pattern: /certutil(?:\.exe)?.*?-urlcache.*?http/i,
        type: 'Certutil Download (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /bitsadmin(?:\.exe)?.*?\/transfer/i,
        type: 'BITS Transfer (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /msiexec(?:\.exe)?.*?\/i.*?http/i,
        type: 'MSI Remote Install (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /msiexec(?:\.exe)?.*?\/q.*?\/i/i,
        type: 'MSI Quiet Install (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /mshta(?:\.exe)?.*?http/i,
        type: 'MSHTA Remote Execution (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /regsvr32(?:\.exe)?.*?\/[si].*?http/i,
        type: 'Regsvr32 Squiblydoo (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /rundll32(?:\.exe)?.*?http/i,
        type: 'Rundll32 Remote DLL (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /rundll32(?:\.exe)?.*?javascript:/i,
        type: 'Rundll32 JavaScript (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /wmic.*?process.*?call.*?create/i,
        type: 'WMIC Process Creation (LOLBin)',
        severity: 'high'
      },
      {
        pattern: /cmstp(?:\.exe)?.*?\/[sn].*?\.inf/i,
        type: 'CMSTP INF Execution (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /installutil(?:\.exe)?.*?\.dll/i,
        type: 'InstallUtil DLL (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /regasm(?:\.exe)?.*?\.dll/i,
        type: 'RegAsm Assembly (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /regsvcs(?:\.exe)?.*?\.dll/i,
        type: 'RegSvcs Assembly (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /msbuild(?:\.exe)?.*?\.(?:xml|csproj|proj)/i,
        type: 'MSBuild Inline Task (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /csc(?:\.exe)?.*?\/out:.*?\.exe/i,
        type: 'C# Compiler Execution (LOLBin)',
        severity: 'high'
      },
      {
        pattern: /ieexec(?:\.exe)?.*?http/i,
        type: 'IEExec Remote (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /odbcconf(?:\.exe)?.*?\/[af].*?\.dll/i,
        type: 'ODBC Config DLL (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /pcalua(?:\.exe)?.*?-a.*?\.exe/i,
        type: 'Program Compat Assistant (LOLBin)',
        severity: 'high'
      },
      {
        pattern: /mavinject(?:\.exe)?.*?\/injectrunning/i,
        type: 'Mavinject DLL Injection (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /SyncAppvPublishingServer(?:\.exe)?.*?;.*?(?:powershell|cmd)/i,
        type: 'SyncAppv PowerShell (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /forfiles(?:\.exe)?.*?\/c.*?cmd/i,
        type: 'Forfiles Command Exec (LOLBin)',
        severity: 'high'
      },
      {
        pattern: /hh(?:\.exe)?.*?\.chm::/i,
        type: 'HTML Help Execute (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /expand(?:\.exe)?.*?\.cab/i,
        type: 'Expand CAB Extract (LOLBin)',
        severity: 'medium'
      },
      {
        pattern: /extrac32(?:\.exe)?.*?\.cab/i,
        type: 'Extrac32 CAB Extract (LOLBin)',
        severity: 'medium'
      },
      {
        pattern: /dfsvc(?:\.exe)?.*?http/i,
        type: 'ClickOnce DFSvc (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /presentationhost(?:\.exe)?.*?\.xbap/i,
        type: 'PresentationHost XAML (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /winrm(?:\.exe)?.*?invoke.*?http/i,
        type: 'WinRM Remote Invoke (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /sc(?:\.exe)?.*?(?:create|config).*?binpath/i,
        type: 'Service Create/Modify (LOLBin)',
        severity: 'critical'
      },
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?echo.*?(?:>|>>).*?%temp%.*?\.(?:bat|cmd|vbs|js|ps1)/i,
        type: 'CMD Echo Script to Temp',
        severity: 'critical'
      },
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?echo.*?CreateObject/i,
        type: 'CMD Echo VBScript/JScript',
        severity: 'critical'
      },
      {
        pattern: /CreateObject\s*\(\s*["'](?:WinHttp\.WinHttpRequest|MSXML2\.XMLHTTP|MSXML2\.ServerXMLHTTP|Scripting\.FileSystemObject)/i,
        type: 'VBScript/JScript CreateObject',
        severity: 'critical'
      },
      {
        pattern: /(?:WinHttpRequest|XMLHTTP).*?\.Open.*?http/i,
        type: 'VBScript HTTP Request',
        severity: 'critical'
      },
      {
        pattern: /Execute\s+(?:h|response|obj)\.ResponseText/i,
        type: 'VBScript Execute Remote Response',
        severity: 'critical'
      },
      {
        pattern: /https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
        type: 'IP Address URL',
        severity: 'high'
      },
      {
        pattern: /https?:\/\/[^\/]+:\d{4,5}\//,
        type: 'Non-Standard Port URL',
        severity: 'high'
      }
    ];

    // Bash/Linux patterns (CRITICAL)
    const bashPatterns = [
      {
        pattern: /(?:curl|wget).*?(?:http|ftp).*?\|.*?(?:bash|sh|python|perl|ruby)/i,
        type: 'Bash Pipe Execution',
        severity: 'critical'
      },
      {
        pattern: /(?:curl|wget).*?-o.*?\/tmp.*?;.*?chmod.*?\+x/i,
        type: 'Download and Execute',
        severity: 'critical'
      },
      {
        pattern: /base64\s+-d.*?\|.*?(?:bash|sh)/i,
        type: 'Base64 Decode and Execute',
        severity: 'critical'
      },
      {
        pattern: /nc\s+-[el].*?\d+.*?-e.*?(?:\/bin\/(?:ba)?sh|cmd\.exe)/i,
        type: 'Netcat Reverse Shell',
        severity: 'critical'
      },
      {
        pattern: /\/bin\/(?:ba)?sh\s+-i\s+>&\s+\/dev\/tcp/i,
        type: 'Bash Reverse Shell',
        severity: 'critical'
      }
    ];

    // Registry manipulation (CRITICAL)
    const registryPatterns = [
      {
        pattern: /reg(?:\.exe)?.*?add.*?(?:HKCU|HKLM).*?(?:Run|RunOnce)/i,
        type: 'Registry Persistence',
        severity: 'critical'
      },
      {
        pattern: /reg(?:\.exe)?.*?delete.*?(?:Windows Defender|Security)/i,
        type: 'Security Software Removal',
        severity: 'critical'
      }
    ];

    // Obfuscation indicators (HIGH)
    const obfuscationPatterns = [
      {
        pattern: /\^{5,}/,
        type: 'Excessive Caret Obfuscation',
        severity: 'high'
      },
      {
        pattern: /`{5,}/,
        type: 'Excessive Backtick Obfuscation',
        severity: 'high'
      },
      {
        pattern: /\[char\]/gi,
        type: 'Character Code Obfuscation',
        severity: 'high'
      },
      {
        pattern: /frombase64string|::FromBase64String/gi,
        type: 'Base64 Decoding',
        severity: 'high'
      }
    ];

    // Generic LOLBin catch-all patterns (HIGH)
    // Catches LOLBin binary names even without specific argument combinations
    const lolbinGenericPatterns = [
      { pattern: /\brundll32(?:\.exe)?\s/i, type: 'Generic LOLBin: rundll32', severity: 'high' },
      { pattern: /\bregsvr32(?:\.exe)?\s/i, type: 'Generic LOLBin: regsvr32', severity: 'high' },
      { pattern: /\bmshta(?:\.exe)?\s/i, type: 'Generic LOLBin: mshta', severity: 'high' },
      { pattern: /\bcertutil(?:\.exe)?\s/i, type: 'Generic LOLBin: certutil', severity: 'high' },
      { pattern: /\bbitsadmin(?:\.exe)?\s/i, type: 'Generic LOLBin: bitsadmin', severity: 'high' },
      { pattern: /\bwmic(?:\.exe)?\s/i, type: 'Generic LOLBin: wmic', severity: 'high' },
      { pattern: /\bcmstp(?:\.exe)?\s/i, type: 'Generic LOLBin: cmstp', severity: 'high' },
      { pattern: /\binstallutil(?:\.exe)?\s/i, type: 'Generic LOLBin: installutil', severity: 'high' },
      { pattern: /\bregasm(?:\.exe)?\s/i, type: 'Generic LOLBin: regasm', severity: 'high' },
      { pattern: /\bregsvcs(?:\.exe)?\s/i, type: 'Generic LOLBin: regsvcs', severity: 'high' },
      { pattern: /\bmsbuild(?:\.exe)?\s/i, type: 'Generic LOLBin: msbuild', severity: 'high' },
      { pattern: /\bcsc(?:\.exe)?\s/i, type: 'Generic LOLBin: csc', severity: 'high' },
      { pattern: /\bieexec(?:\.exe)?\s/i, type: 'Generic LOLBin: ieexec', severity: 'high' },
      { pattern: /\bodbcconf(?:\.exe)?\s/i, type: 'Generic LOLBin: odbcconf', severity: 'high' },
      { pattern: /\bpcalua(?:\.exe)?\s/i, type: 'Generic LOLBin: pcalua', severity: 'high' },
      { pattern: /\bmavinject(?:\.exe)?\s/i, type: 'Generic LOLBin: mavinject', severity: 'high' },
      { pattern: /\bSyncAppvPublishingServer(?:\.exe)?\s/i, type: 'Generic LOLBin: SyncAppvPublishingServer', severity: 'high' },
      { pattern: /\bforfiles(?:\.exe)?\s/i, type: 'Generic LOLBin: forfiles', severity: 'high' },
      { pattern: /\bhh(?:\.exe)?\s/i, type: 'Generic LOLBin: hh', severity: 'high' },
      { pattern: /\bdfsvc(?:\.exe)?\s/i, type: 'Generic LOLBin: dfsvc', severity: 'high' },
      { pattern: /\bpresentationhost(?:\.exe)?\s/i, type: 'Generic LOLBin: presentationhost', severity: 'high' },
      { pattern: /\bwinrm(?:\.exe)?\s/i, type: 'Generic LOLBin: winrm', severity: 'high' },
      { pattern: /\bmsiexec(?:\.exe)?\s/i, type: 'Generic LOLBin: msiexec', severity: 'high' },
      { pattern: /\bmsdt(?:\.exe)?\s/i, type: 'Generic LOLBin: msdt', severity: 'high' },
      { pattern: /\bdnscmd(?:\.exe)?\s/i, type: 'Generic LOLBin: dnscmd', severity: 'high' },
      { pattern: /\bcontrol(?:\.exe)?\s/i, type: 'Generic LOLBin: control', severity: 'high' },
      { pattern: /\binfdefaultinstall(?:\.exe)?\s/i, type: 'Generic LOLBin: infdefaultinstall', severity: 'high' },
      { pattern: /\bdesktopimgdownldr(?:\.exe)?\s/i, type: 'Generic LOLBin: desktopimgdownldr', severity: 'high' },
      { pattern: /\beudcedit(?:\.exe)?\s/i, type: 'Generic LOLBin: eudcedit', severity: 'high' },
      { pattern: /\bbash(?:\.exe)?\s/i, type: 'Generic LOLBin: bash', severity: 'high' },
      { pattern: /\bwsl(?:\.exe)?\s/i, type: 'Generic LOLBin: wsl', severity: 'high' },
      { pattern: /\bxwizard(?:\.exe)?\s/i, type: 'Generic LOLBin: xwizard', severity: 'high' },
      { pattern: /\bverclsid(?:\.exe)?\s/i, type: 'Generic LOLBin: verclsid', severity: 'high' },
      { pattern: /\bbginfo(?:\.exe)?\s/i, type: 'Generic LOLBin: bginfo', severity: 'high' },
      { pattern: /\bdiskshadow(?:\.exe)?\s/i, type: 'Generic LOLBin: diskshadow', severity: 'high' },
      { pattern: /\breplace(?:\.exe)?\s/i, type: 'Generic LOLBin: replace', severity: 'high' },
      { pattern: /\brpcping(?:\.exe)?\s/i, type: 'Generic LOLBin: rpcping', severity: 'high' },
      { pattern: /\bftp(?:\.exe)?\s/i, type: 'Generic LOLBin: ftp', severity: 'high' },
      { pattern: /\bexplorer(?:\.exe)?\s/i, type: 'Generic LOLBin: explorer', severity: 'high' }
    ];

    // UNC/WebDAV remote path pattern (CRITICAL)
    const uncPatterns = [
      {
        pattern: /\\\\[^\s\\]+@\d+\\[^\s]+/,
        type: 'UNC/WebDAV Remote Path',
        severity: 'critical'
      }
    ];

    // Suspicious environment variables (HIGH)
    const envVarPatterns = [
      {
        pattern: /%temp%.*?\.(?:exe|bat|cmd|ps1|vbs|js)/i,
        type: 'Temp Directory Executable',
        severity: 'high'
      },
      {
        pattern: /%appdata%.*?\.(?:exe|bat|cmd|ps1|vbs|js)/i,
        type: 'AppData Executable',
        severity: 'high'
      },
      {
        pattern: /%programdata%.*?\.(?:exe|bat|cmd|ps1|vbs|js)/i,
        type: 'ProgramData Executable',
        severity: 'high'
      }
    ];

    // Check all pattern categories
    const allPatterns = [
      ...powershellPatterns,
      ...cmdPatterns,
      ...bashPatterns,
      ...registryPatterns,
      ...obfuscationPatterns,
      ...envVarPatterns,
      ...lolbinGenericPatterns,
      ...uncPatterns
    ];

    for (const { pattern, type, severity } of allPatterns) {
      if (pattern.test(text)) {
        threats.push({ type, severity });
      }
    }

    // Check for cryptocurrency addresses (address swapping attack)
    const cryptoPatterns = {
      Bitcoin: /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/,
      Ethereum: /\b0x[a-fA-F0-9]{40}\b/,
      Litecoin: /\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b/,
      Monero: /\b4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b/
    };

    for (const [currency, pattern] of Object.entries(cryptoPatterns)) {
      if (pattern.test(text)) {
        threats.push({
          type: `${currency} Address`,
          severity: 'high'
        });
      }
    }

    // Check for private keys
    if (/-----BEGIN (?:RSA |DSA |EC )?PRIVATE KEY-----/.test(text)) {
      threats.push({
        type: 'Private Key',
        severity: 'critical'
      });
    }

    return {
      safe: threats.length === 0,
      threats
    };
  }

  /**
   * Block clipboard operation and show alert
   */
  function blockClipboardOperation(threats, source, blockedContent = '') {
    const threatTypes = threats.map(t => t.type).join(', ');
    const blockId = `block-${Date.now()}`;

    console.error(`[PhishProtect] BLOCKED clipboard injection attempt!`);
    console.error(`[PhishProtect] Detected threats: ${threatTypes}`);
    console.error(`[PhishProtect] Source: ${source}`);

    // Store blocked content for detailed view
    const blockData = {
      id: blockId,
      threats: threats,
      source: source,
      content: blockedContent,
      timestamp: Date.now(),
      url: window.location.href
    };

    // Show user-visible alert
    const alertDiv = document.createElement('div');
    alertDiv.id = blockId;
    alertDiv.style.cssText = `
      position: fixed;
      top: 20px;
      right: 20px;
      background: #d32f2f;
      color: #fff;
      padding: 16px 24px;
      border-radius: 8px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.3);
      z-index: 2147483647;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      font-size: 14px;
      max-width: 400px;
      animation: slideIn 0.3s ease-out;
      cursor: pointer;
      transition: transform 0.2s;
    `;

    alertDiv.innerHTML = `
      <div style="display: flex; align-items: center; gap: 12px;">
        <span style="font-size: 24px;">🛡️</span>
        <div style="flex: 1;">
          <div style="font-weight: 700; margin-bottom: 4px;">Clipboard Attack Blocked</div>
          <div style="font-size: 12px; opacity: 0.9; margin-bottom: 8px;">
            ${threats.length} threat${threats.length > 1 ? 's' : ''} detected
          </div>
          <div style="font-size: 11px; opacity: 0.8; background: rgba(255,255,255,0.2); padding: 4px 8px; border-radius: 4px; display: inline-block;">
            Click for details
          </div>
        </div>
      </div>
    `;

    // Add hover effect
    alertDiv.addEventListener('mouseenter', () => {
      alertDiv.style.transform = 'scale(1.02)';
    });

    alertDiv.addEventListener('mouseleave', () => {
      alertDiv.style.transform = 'scale(1)';
    });

    // Click to show details
    alertDiv.addEventListener('click', () => {
      showDetailedView(blockData);
    });

    // Add animation
    const style = document.createElement('style');
    style.textContent = `
      @keyframes slideIn {
        from { transform: translateX(400px); opacity: 0; }
        to { transform: translateX(0); opacity: 1; }
      }
    `;
    document.head.appendChild(style);

    document.body.appendChild(alertDiv);

    // Auto-remove after 10 seconds
    setTimeout(() => {
      alertDiv.style.animation = 'slideIn 0.3s ease-out reverse';
      setTimeout(() => alertDiv.remove(), 300);
    }, 10000);

    // Capture stack trace at detection point
    let stackTrace = null;
    try {
      const stack = new Error().stack;
      stackTrace = stack.split('\n')
        .filter(line => !line.includes('chrome-extension://'))
        .slice(0, 10)
        .map(line => line.trim());
    } catch (e) {}

    // Capture inline script sources (injected script can access DOM but not fetch)
    let inlineScripts = [];
    try {
      const scriptEls = document.querySelectorAll('script:not([src])');
      let count = 0;
      for (const el of scriptEls) {
        if (count >= 3) break;
        const text = el.textContent || '';
        if (!text.trim() || text.length < 20) continue;
        const lines = text.split('\n');
        if (lines.length > 500) continue;
        inlineScripts.push({
          index: count,
          lineCount: lines.length,
          preview: text.substring(0, 300)
        });
        count++;
      }
    } catch (e) {}

    // Notify background script
    try {
      window.postMessage({
        type: 'phishprotect-clipboard-blocked',
        threats: threats,
        source: source,
        timestamp: Date.now(),
        contentPreview: blockedContent.substring(0, 2000), // Up to 2000 chars for telemetry evidence
        stackTrace: stackTrace,
        inlineScripts: inlineScripts
      }, '*');
    } catch (e) {
      // Ignore if can't communicate
    }
  }

  /**
   * Show detailed view of blocked content
   */
  function showDetailedView(blockData) {
    // Remove any existing detail view
    const existing = document.getElementById('phishprotect-detail-modal');
    if (existing) {
      existing.remove();
    }

    // Create modal overlay
    const modal = document.createElement('div');
    modal.id = 'phishprotect-detail-modal';
    modal.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.8);
      z-index: 2147483647;
      display: flex;
      justify-content: center;
      align-items: center;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      animation: fadeIn 0.2s;
      direction: ltr;
      text-align: left;
    `;

    const modalContent = document.createElement('div');
    modalContent.style.cssText = `
      background: #fff;
      border-radius: 12px;
      max-width: 700px;
      max-height: 80vh;
      width: 90%;
      box-shadow: 0 20px 60px rgba(0,0,0,0.3);
      display: flex;
      flex-direction: column;
      direction: ltr;
      text-align: left;
    `;

    const threatList = blockData.threats.map(t => `
      <div style="background: #f8f9fa; padding: 8px 12px; border-radius: 6px; margin: 4px 0;">
        <div style="font-weight: 600; color: #dc3545; font-size: 13px;">${t.type}</div>
        <div style="font-size: 11px; color: #6c757d; margin-top: 2px;">Severity: ${t.severity}</div>
      </div>
    `).join('');

    const contentPreview = blockData.content.length > 500
      ? blockData.content.substring(0, 500) + '...'
      : blockData.content;

    modalContent.innerHTML = `
      <!-- Fixed Header -->
      <div style="padding: 24px 24px 16px 24px; border-bottom: 1px solid #dee2e6; flex-shrink: 0;">
        <div style="display: flex; justify-content: space-between; align-items: center;">
          <h2 style="margin: 0; font-size: 20px; color: #212529;">🛡️ Blocked Clipboard Attack</h2>
          <button id="close-detail-modal" style="background: none; border: none; font-size: 24px; cursor: pointer; color: #6c757d; padding: 0; line-height: 1;">×</button>
        </div>
      </div>

      <!-- Scrollable Content -->
      <div style="flex: 1; overflow-y: auto; padding: 20px 24px;">
        <div style="margin-bottom: 20px;">
          <div style="font-size: 12px; font-weight: 600; color: #6c757d; text-transform: uppercase; margin-bottom: 8px;">Detected Threats</div>
          ${threatList}
        </div>

        <div style="margin-bottom: 20px;">
          <div style="font-size: 12px; font-weight: 600; color: #6c757d; text-transform: uppercase; margin-bottom: 8px;">Blocked Content</div>
          <div style="background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 12px; font-family: 'Courier New', monospace; font-size: 12px; color: #212529; white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; direction: ltr;">
${contentPreview}
          </div>
          <div style="font-size: 11px; color: #6c757d; margin-top: 4px;">
            Length: ${blockData.content.length} characters
          </div>
        </div>

        <div>
          <div style="font-size: 12px; font-weight: 600; color: #6c757d; text-transform: uppercase; margin-bottom: 8px;">Additional Information</div>
          <div style="background: #f8f9fa; padding: 12px; border-radius: 6px; font-size: 12px;">
            <div><strong>Source:</strong> ${blockData.source}</div>
            <div style="margin-top: 4px;"><strong>Time:</strong> ${new Date(blockData.timestamp).toLocaleString()}</div>
            <div style="margin-top: 4px;"><strong>Page:</strong> ${blockData.url}</div>
          </div>
        </div>
      </div>

      <!-- Fixed Footer -->
      <div style="padding: 16px 24px 24px 24px; border-top: 1px solid #dee2e6; flex-shrink: 0;">
        <div style="display: flex; gap: 12px;">
          <button id="learn-more-button" style="flex: 1; background: #06b6d4; color: #fff; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 600; cursor: pointer; font-size: 14px;">
            Learn More
          </button>
          <button id="report-fp-button" style="flex: 1; background: #ffc107; color: #000; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 600; cursor: pointer; font-size: 14px;">
            Report False Positive
          </button>
          <button id="close-detail-button" style="flex: 1; background: #6c757d; color: #fff; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 600; cursor: pointer; font-size: 14px;">
            Close
          </button>
        </div>

        <div id="fp-report-status" style="margin-top: 12px; padding: 8px; border-radius: 6px; font-size: 12px; display: none;"></div>
      </div>
    `;

    modal.appendChild(modalContent);
    document.body.appendChild(modal);

    // Close button handlers
    document.getElementById('close-detail-modal').addEventListener('click', () => {
      modal.remove();
    });

    document.getElementById('close-detail-button').addEventListener('click', () => {
      modal.remove();
    });

    // Learn More button
    document.getElementById('learn-more-button').addEventListener('click', () => {
      // Determine the primary threat type to build a detector hash
      const primaryThreat = blockData.threats && blockData.threats.length > 0
        ? blockData.threats[0].type : '';
      window.postMessage({
        type: 'phishprotect-open-techniques',
        detector: primaryThreat
      }, '*');
      modal.remove();
    });

    // Click outside to close
    modal.addEventListener('click', (e) => {
      if (e.target === modal) {
        modal.remove();
      }
    });

    // Report false positive
    document.getElementById('report-fp-button').addEventListener('click', () => {
      reportFalsePositive(blockData);
    });

    // Add fade-in animation
    const styleTag = document.createElement('style');
    styleTag.textContent = `
      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }
    `;
    document.head.appendChild(styleTag);
  }

  /**
   * Report false positive to background script
   */
  function reportFalsePositive(blockData) {
    const statusDiv = document.getElementById('fp-report-status');
    const reportButton = document.getElementById('report-fp-button');

    reportButton.disabled = true;
    reportButton.textContent = 'Submitting...';

    // Send report to background
    try {
      window.postMessage({
        type: 'phishprotect-false-positive-report',
        blockData: {
          threats: blockData.threats,
          source: blockData.source,
          contentHash: hashString(blockData.content), // Hash instead of full content
          contentLength: blockData.content.length,
          timestamp: blockData.timestamp,
          url: blockData.url,
          userAgent: navigator.userAgent
        }
      }, '*');

      statusDiv.style.display = 'block';
      statusDiv.style.background = '#d4edda';
      statusDiv.style.color = '#155724';
      statusDiv.textContent = '✓ False positive report submitted. Thank you for helping improve PhishProtect!';

      reportButton.textContent = 'Reported';
      reportButton.style.background = '#28a745';
      reportButton.style.color = '#fff';
    } catch (e) {
      statusDiv.style.display = 'block';
      statusDiv.style.background = '#f8d7da';
      statusDiv.style.color = '#721c24';
      statusDiv.textContent = '✗ Failed to submit report. Please try again.';

      reportButton.disabled = false;
      reportButton.textContent = 'Report False Positive';
    }
  }

  /**
   * Simple string hash for privacy
   */
  function hashString(str) {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash;
    }
    return Math.abs(hash).toString(16).padStart(16, '0');
  }

  // Intercept navigator.clipboard.writeText()
  if (navigator.clipboard && originalWriteText) {
    navigator.clipboard.writeText = async function(text) {
      try { if (typeof text === 'string') recordWrite('', text); } catch (_) {}
      const analysis = analyzeClipboardContent(text);

      if (!analysis.safe) {
        blockClipboardOperation(analysis.threats, 'navigator.clipboard.writeText()', text);
        throw new DOMException('Clipboard write blocked by PhishProtect', 'NotAllowedError');
      }

      return originalWriteText.call(this, text);
    };
    console.log('[PhishProtect] Intercepted navigator.clipboard.writeText');
  }

  // Intercept navigator.clipboard.write()
  if (navigator.clipboard && originalWrite) {
    navigator.clipboard.write = async function(items) {
      // Check text items
      for (const item of items) {
        if (item.types.includes('text/plain')) {
          const blob = await item.getType('text/plain');
          const text = await blob.text();

          try { if (typeof text === 'string') recordWrite('', text); } catch (_) {}
          const analysis = analyzeClipboardContent(text);
          if (!analysis.safe) {
            blockClipboardOperation(analysis.threats, 'navigator.clipboard.write()', text);
            throw new DOMException('Clipboard write blocked by PhishProtect', 'NotAllowedError');
          }
        }
      }

      return originalWrite.call(this, items);
    };
    console.log('[PhishProtect] Intercepted navigator.clipboard.write');
  }

  // Count clipboard reads (excessive monitoring = potential data theft).
  // Count + call through; we don't block or alter reads.
  if (navigator.clipboard && originalReadText) {
    navigator.clipboard.readText = function(...a) {
      try { clipState.clipboardReadCount++; clipScheduleEmit(); } catch (_) {}
      return originalReadText.apply(this, a);
    };
  }
  if (navigator.clipboard && originalRead) {
    navigator.clipboard.read = function(...a) {
      try { clipState.clipboardReadCount++; clipScheduleEmit(); } catch (_) {}
      return originalRead.apply(this, a);
    };
  }

  // Intercept document.execCommand('copy')
  document.execCommand = function(command, ...args) {
    if (command === 'copy') {
      const selection = window.getSelection().toString();

      const analysis = analyzeClipboardContent(selection);
      if (!analysis.safe) {
        blockClipboardOperation(analysis.threats, 'document.execCommand("copy")', selection);
        return false;
      }
    }

    return originalExecCommand.call(this, command, ...args);
  };
  console.log('[PhishProtect] Intercepted document.execCommand');

  // Intercept clipboard event listeners (copy event manipulation)
  EventTarget.prototype.addEventListener = function(type, listener, options) {
    if (type === 'copy' || type === 'cut') {
      const wrappedListener = function(event) {
        // Capture what the user actually selected BEFORE the page's handler runs
        // (a poisoning handler may clear the selection or call setData).
        let userSelected = '';
        try { userSelected = window.getSelection().toString(); } catch (_) {}

        const result = listener.call(this, event);

        // Check if clipboardData was modified
        if (event.clipboardData) {
          const text = event.clipboardData.getData('text/plain');

          // Behavioral state: userSelected vs page-modified clipboard content
          // (feeds pastejacking / crypto-swap / command-injection poisoning).
          try { recordCopy(userSelected, text); } catch (_) {}

          if (text) {
            const analysis = analyzeClipboardContent(text);
            if (!analysis.safe) {
              event.preventDefault();
              blockClipboardOperation(analysis.threats, `${type} event listener`, text);
              return false;
            }
          }
        }

        return result;
      };

      return originalAddEventListener.call(this, type, wrappedListener, options);
    }

    return originalAddEventListener.call(this, type, listener, options);
  };
  console.log('[PhishProtect] Intercepted clipboard event listeners');

  console.log('[PhishProtect] ✅ Clipboard protection active');
})();
