// Content Detector - DOM-based detection module
// Used by background script for deep page analysis
// Can be injected into tabs for comprehensive DOM inspection

export class ContentDetector {
  constructor() {
    this.cache = new Map();
  }

  /**
   * Analyze page for clickjacking attempts
   * @returns {object} - Detection result
   */
  detectClickjacking() {
    const iframes = document.getElementsByTagName('iframe');
    const findings = [];

    for (const iframe of iframes) {
      const style = window.getComputedStyle(iframe);
      const opacity = parseFloat(style.opacity);
      const zIndex = parseInt(style.zIndex) || 0;
      const position = style.position;

      // Check for suspicious iframe overlay
      if (opacity < 0.1 && zIndex > 1000 && (position === 'absolute' || position === 'fixed')) {
        findings.push({
          type: 'clickjacking',
          element: 'iframe',
          opacity,
          zIndex,
          position,
          src: iframe.src,
          severity: 'critical'
        });
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.length * 5
    };
  }

  /**
   * Detect fake browser UI elements
   * @returns {object} - Detection result
   */
  detectFakeBrowserUI() {
    const findings = [];

    // Look for elements mimicking browser chrome
    const suspiciousSelectors = [
      'div[class*="chrome"]',
      'div[class*="browser"]',
      'div[class*="address"]',
      'div[class*="url-bar"]'
    ];

    for (const selector of suspiciousSelectors) {
      const elements = document.querySelectorAll(selector);
      for (const element of elements) {
        const style = window.getComputedStyle(element);
        const position = style.position;
        const top = parseInt(style.top) || 0;
        const zIndex = parseInt(style.zIndex) || 0;

        // Check if positioned at top with high z-index
        if ((position === 'fixed' || position === 'absolute') && top < 100 && zIndex > 1000) {
          findings.push({
            type: 'fake-browser-ui',
            element: element.tagName,
            className: element.className,
            position,
            top,
            zIndex,
            severity: 'high'
          });
        }
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.length * 4
    };
  }

  /**
   * Detect hidden credential harvesting forms
   * @returns {object} - Detection result
   */
  detectHiddenForms() {
    const forms = document.getElementsByTagName('form');
    const findings = [];

    for (const form of forms) {
      const style = window.getComputedStyle(form);
      const hasPasswordField = Array.from(form.getElementsByTagName('input'))
        .some(input => input.type === 'password');

      // Check if form is hidden but has password field
      if (hasPasswordField) {
        const isHidden = style.display === 'none' ||
                        style.visibility === 'hidden' ||
                        parseFloat(style.opacity) < 0.1 ||
                        parseInt(style.height) < 10 ||
                        parseInt(style.width) < 10;

        if (isHidden) {
          findings.push({
            type: 'hidden-credential-form',
            display: style.display,
            visibility: style.visibility,
            opacity: style.opacity,
            action: form.action,
            severity: 'critical'
          });
        }
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.length * 5
    };
  }

  /**
   * Detect autofill harvesting attempts
   * @returns {object} - Detection result
   */
  detectAutofillHarvesting() {
    const inputs = document.querySelectorAll('input[autocomplete]');
    const findings = [];

    const sensitiveAutocomplete = [
      'cc-number', 'cc-exp', 'cc-csc',
      'email', 'tel', 'street-address',
      'postal-code', 'country'
    ];

    for (const input of inputs) {
      const autocomplete = input.getAttribute('autocomplete');
      if (sensitiveAutocomplete.includes(autocomplete)) {
        const style = window.getComputedStyle(input);

        // Check if hidden
        const isHidden = style.display === 'none' ||
                        style.visibility === 'hidden' ||
                        parseFloat(style.opacity) < 0.1 ||
                        parseInt(style.height) < 5 ||
                        parseInt(style.width) < 5 ||
                        parseInt(style.left) < -1000 ||
                        parseInt(style.top) < -1000;

        if (isHidden) {
          findings.push({
            type: 'autofill-harvesting',
            autocomplete,
            name: input.name,
            isOffScreen: parseInt(style.left) < -1000 || parseInt(style.top) < -1000,
            severity: 'critical'
          });
        }
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.length * 4
    };
  }

  /**
   * Detect overlay credential prompts
   * @returns {object} - Detection result
   */
  detectCredentialOverlays() {
    const findings = [];

    // Look for full-page overlays with credential fields
    const overlays = document.querySelectorAll('div');

    for (const overlay of overlays) {
      const style = window.getComputedStyle(overlay);
      const position = style.position;
      const zIndex = parseInt(style.zIndex) || 0;

      // Check for full-page overlay
      if ((position === 'fixed' || position === 'absolute') && zIndex > 1000) {
        const width = overlay.offsetWidth;
        const height = overlay.offsetHeight;
        const isFullPage = width > window.innerWidth * 0.8 && height > window.innerHeight * 0.8;

        if (isFullPage) {
          // Check for password fields inside
          const passwordFields = overlay.querySelectorAll('input[type="password"]');
          if (passwordFields.length > 0) {
            // Check for urgency language
            const text = overlay.textContent.toLowerCase();
            const hasUrgency = /session.*expir|log.*in.*again|verif|confirm.*identity/.test(text);

            findings.push({
              type: 'credential-overlay',
              passwordFields: passwordFields.length,
              hasUrgency,
              zIndex,
              severity: hasUrgency ? 'critical' : 'high'
            });
          }
        }
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.reduce((sum, f) => sum + (f.severity === 'critical' ? 5 : 3), 0)
    };
  }

  /**
   * Detect dialog traps (infinite alerts/confirms)
   * @returns {object} - Detection result
   */
  detectDialogTraps() {
    const findings = [];

    // Check for beforeunload handlers (potential dialog trap)
    const scripts = document.getElementsByTagName('script');
    for (const script of scripts) {
      const content = script.textContent;
      if (/beforeunload|onbeforeunload/.test(content) && /return\s*['"]/i.test(content)) {
        findings.push({
          type: 'beforeunload-trap',
          severity: 'medium'
        });
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.length * 2
    };
  }

  /**
   * Detect formjacking (payment form interception)
   * @returns {object} - Detection result
   */
  detectFormjacking() {
    const findings = [];

    // Look for payment forms
    const paymentInputs = document.querySelectorAll('input[name*="card"], input[name*="cvv"], input[name*="ccv"], input[autocomplete="cc-number"]');

    for (const input of paymentInputs) {
      // Check for suspicious event listeners
      const listeners = getEventListeners ? getEventListeners(input) : null;
      if (listeners && (listeners.input || listeners.change || listeners.keyup)) {
        findings.push({
          type: 'formjacking-listener',
          inputName: input.name,
          autocomplete: input.autocomplete,
          hasListeners: true,
          severity: 'critical'
        });
      }
    }

    // Check for external scripts on payment pages
    if (paymentInputs.length > 0) {
      const scripts = document.querySelectorAll('script[src]');
      for (const script of scripts) {
        const src = script.src;
        const domain = new URL(window.location.href).hostname;
        const scriptDomain = new URL(src).hostname;

        if (scriptDomain !== domain && !this.isTrustedPaymentDomain(scriptDomain)) {
          findings.push({
            type: 'external-script-on-payment',
            scriptSrc: scriptDomain,
            severity: 'high'
          });
        }
      }
    }

    return {
      matched: findings.length > 0,
      findings,
      riskScore: findings.reduce((sum, f) => sum + (f.severity === 'critical' ? 5 : 3), 0)
    };
  }

  /**
   * Run all DOM-based detectors
   * @returns {object} - Aggregated detection results
   */
  async runAllDetectors() {
    const results = {
      clickjacking: this.detectClickjacking(),
      fakeBrowserUI: this.detectFakeBrowserUI(),
      hiddenForms: this.detectHiddenForms(),
      autofillHarvesting: this.detectAutofillHarvesting(),
      credentialOverlays: this.detectCredentialOverlays(),
      dialogTraps: this.detectDialogTraps(),
      formjacking: this.detectFormjacking()
    };

    // Aggregate findings
    const allFindings = [];
    let totalRiskScore = 0;

    for (const [detector, result] of Object.entries(results)) {
      if (result.matched) {
        allFindings.push(...result.findings.map(f => ({
          ...f,
          detector
        })));
        totalRiskScore += result.riskScore;
      }
    }

    return {
      matched: allFindings.length > 0,
      findings: allFindings,
      riskScore: totalRiskScore,
      detectorResults: results,
      timestamp: Date.now()
    };
  }

  /**
   * Check if domain is trusted for payment processing
   * @param {string} domain - Domain to check
   * @returns {boolean} - True if trusted
   */
  isTrustedPaymentDomain(domain) {
    const trustedDomains = [
      'stripe.com',
      'paypal.com',
      'square.com',
      'braintreegateway.com',
      'checkout.com',
      'adyen.com'
    ];

    return trustedDomains.some(trusted => domain.endsWith(trusted));
  }

  /**
   * Get page metadata
   * @returns {object} - Page metadata
   */
  getPageMetadata() {
    return {
      url: window.location.href,
      title: document.title,
      formCount: document.getElementsByTagName('form').length,
      iframeCount: document.getElementsByTagName('iframe').length,
      scriptCount: document.getElementsByTagName('script').length,
      inputCount: document.getElementsByTagName('input').length,
      hasPasswordFields: document.querySelectorAll('input[type="password"]').length > 0,
      hasPaymentFields: document.querySelectorAll('input[autocomplete*="cc-"]').length > 0
    };
  }
}

// Export for use in background script
if (typeof module !== 'undefined' && module.exports) {
  module.exports = { ContentDetector };
}
