// Fake Chrome Detector - Detects fake browser chrome/address bar indicators
// Browser Techniques Line 40: Fake chrome/address bar indicators
// DOM mimics browser chrome to appear legit

import { BaseDetector } from '../base-detector.js';

export class FakeChromeDetector extends BaseDetector {
  constructor(config = {}) {
    super({
      name: 'fake-chrome',
      category: 'social-engineering',
      version: '1.0.0',
      description: 'Detects fake browser chrome and address bar elements',
      weight: 3,
      severity: 'high',
      ...config
    });
  }

  async detect(target, ruleRegistry) {
    const findings = [];

    // This detector requires DOM data from content script
    const dom = target.dom || {};

    if (!dom.topElements && !dom.images && !dom.svgs && !dom.suspiciousText) {
      return this.createResult(false, [], 0);
    }

    const rules = ruleRegistry.getRules('social-engineering', 'fake-chrome');

    if (!rules) {
      return this.createResult(false, [], 0);
    }

    // 1. Detect elements positioned at top of viewport (fake address bar)
    if (dom.topElements && Array.isArray(dom.topElements)) {
      for (const element of dom.topElements) {
        // Check if element looks like a browser chrome
        const isSuspicious = this.isFakeChromeCandidate(element, rules);

        if (isSuspicious.score > 2) {
          findings.push(this.createFinding({
            pattern: 'fake-address-bar',
            matched: element.tagName || 'unknown element',
            description: 'Suspicious element resembling browser address bar',
            severity: isSuspicious.score > 3 ? 'high' : 'medium',
            weight: isSuspicious.score,
            metadata: {
              reasons: isSuspicious.reasons,
              position: element.position,
              top: element.top,
              width: element.width,
              technique: 'fake-browser-chrome'
            }
          }));
        }
      }
    }

    // 2. Detect fake padlock/security icons
    if (rules.securityIconPatterns) {
      const allImages = [
        ...(dom.images || []),
        ...(dom.svgs || []),
        ...(dom.iconElements || [])
      ];

      for (const icon of allImages) {
        for (const pattern of rules.securityIconPatterns) {
          if (
            (icon.src && this.testPattern(pattern.pattern, icon.src)) ||
            (icon.className && this.testPattern(pattern.pattern, icon.className)) ||
            (icon.innerText && this.testPattern(pattern.pattern, icon.innerText))
          ) {
            // Check if icon is near top of page (more suspicious)
            const isNearTop = icon.top < 100;

            findings.push(this.createFinding({
              pattern: 'fake-security-icon',
              matched: icon.src || icon.className || 'security icon',
              description: pattern.description,
              severity: isNearTop ? 'high' : 'medium',
              weight: isNearTop ? 4 : 2,
              metadata: {
                iconType: pattern.type,
                position: icon.position,
                top: icon.top,
                technique: 'fake-security-indicator'
              }
            }));
          }
        }
      }
    }

    // 3. Detect fake SSL certificate indicators
    if (dom.suspiciousText && Array.isArray(dom.suspiciousText)) {
      for (const textElement of dom.suspiciousText) {
        const text = textElement.text || '';

        // Check for SSL/security-related text near top
        if (rules.sslIndicatorPatterns) {
          for (const pattern of rules.sslIndicatorPatterns) {
            if (this.testPattern(pattern.pattern, text)) {
              const isNearTop = textElement.top < 100;

              findings.push(this.createFinding({
                pattern: 'fake-ssl-indicator',
                matched: text.substring(0, 50),
                description: pattern.description,
                severity: isNearTop ? 'high' : 'medium',
                weight: isNearTop ? 3 : 2,
                metadata: {
                  position: textElement.position,
                  top: textElement.top,
                  technique: 'fake-certificate-info'
                }
              }));
            }
          }
        }

        // Check for fake URL text (text that looks like a URL but isn't in actual address bar)
        if (this.looksLikeURL(text) && textElement.top < 150) {
          findings.push(this.createFinding({
            pattern: 'fake-url-display',
            matched: text.substring(0, 50),
            description: 'Fake URL displayed in page content (not real address bar)',
            severity: 'medium',
            weight: 2,
            metadata: {
              url: text,
              top: textElement.top,
              technique: 'url-spoofing'
            }
          }));
        }
      }
    }

    // 4. Detect fake browser notification bars
    if (dom.notificationBars && Array.isArray(dom.notificationBars)) {
      for (const bar of dom.notificationBars) {
        if (bar.looksLikeBrowserNotification) {
          findings.push(this.createFinding({
            pattern: 'fake-browser-notification',
            matched: bar.text || 'notification bar',
            description: 'Fake browser notification bar detected',
            severity: 'medium',
            weight: 3,
            metadata: {
              text: bar.text,
              top: bar.top,
              technique: 'fake-notification'
            }
          }));
        }
      }
    }

    // 5. Detect fullscreen + fake chrome combination
    if (target.isFullscreen && findings.length > 0) {
      findings.push(this.createFinding({
        pattern: 'fullscreen-fake-chrome',
        matched: 'Fullscreen mode with fake browser chrome',
        description: 'Page in fullscreen with fake browser UI (critical attack)',
        severity: 'critical',
        weight: 5,
        metadata: {
          technique: 'fullscreen-spoofing'
        }
      }));
    }

    const matched = findings.length > 0;
    const riskScore = findings.reduce((sum, f) => sum + (f.weight || 1), 0);

    return this.createResult(matched, findings, riskScore);
  }

  isFakeChromeCandidate(element, rules) {
    let score = 0;
    const reasons = [];

    // Check position (absolute/fixed at top)
    if (
      (element.position === 'absolute' || element.position === 'fixed') &&
      element.top < (rules.topThreshold || 50)
    ) {
      score += 1;
      reasons.push('Positioned at top of viewport');
    }

    // Check width (covers most of viewport)
    if (element.widthPercent > 80) {
      score += 1;
      reasons.push('Spans most of viewport width');
    }

    // Check background color (often light gray/white like browser chrome)
    if (
      rules.chromeColors &&
      rules.chromeColors.some(color => element.backgroundColor?.includes(color))
    ) {
      score += 1;
      reasons.push('Background color resembles browser chrome');
    }

    // Check for border/shadow (browser chrome styling)
    if (element.hasBorder || element.hasBoxShadow) {
      score += 1;
      reasons.push('Has border or shadow like browser UI');
    }

    // Check for input-like children (fake address bar)
    if (element.hasInputChild) {
      score += 2;
      reasons.push('Contains input field (fake address bar)');
    }

    // Check for icon children
    if (element.hasIconChild) {
      score += 1;
      reasons.push('Contains icon elements');
    }

    // Check z-index (should be on top)
    if (element.zIndex > 9000) {
      score += 1;
      reasons.push('High z-index (attempting to overlay everything)');
    }

    return { score, reasons };
  }

  looksLikeURL(text) {
    // Check if text looks like a URL
    const urlPatterns = [
      /^https?:\/\//i,
      /^www\./i,
      /\.(com|net|org|edu|gov|io|co)\//i,
      /^chrome:\/\//i,
      /^file:\/\//i
    ];

    return urlPatterns.some(pattern => pattern.test(text));
  }
}
