// Browser-in-Browser Detector - Detects fake browser windows
// Browser Techniques Line 39: Browser-in-the-browser (fake windows)
// CSS/JS simulates separate browser windows with spoofed address bars/padlocks

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

export class BrowserInBrowserDetector extends BaseDetector {
  constructor(config = {}) {
    super({
      name: 'browser-in-browser',
      category: 'social-engineering',
      version: '1.0.0',
      description: 'Detects fake browser windows and SSO popup mimicry',
      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.modals && !dom.dialogs && !dom.windowLikeElements) {
      return this.createResult(false, [], 0);
    }

    const rules = ruleRegistry.getRules('social-engineering', 'browser-in-browser');

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

    // 1. Detect fake browser window elements
    const windowCandidates = [
      ...(dom.modals || []),
      ...(dom.dialogs || []),
      ...(dom.windowLikeElements || [])
    ];

    for (const element of windowCandidates) {
      const suspicionScore = this.calculateBitBScore(element, rules);

      if (suspicionScore.score >= 3) {
        findings.push(this.createFinding({
          pattern: 'browser-in-browser',
          matched: element.id || element.className || 'window-like element',
          description: 'Fake browser window detected (Browser-in-Browser attack)',
          severity: suspicionScore.score >= 5 ? 'critical' : 'high',
          weight: suspicionScore.score,
          metadata: {
            reasons: suspicionScore.reasons,
            hasAddressBar: element.hasAddressBar,
            hasWindowControls: element.hasWindowControls,
            hasBorder: element.hasBorder,
            technique: 'browser-in-browser'
          }
        }));
      }
    }

    // 2. Detect SSO popup mimicry
    if (rules.ssoProviders) {
      for (const element of windowCandidates) {
        const ssoMatch = this.detectSSOPopupMimicry(element, rules.ssoProviders);

        if (ssoMatch) {
          findings.push(this.createFinding({
            pattern: 'fake-sso-popup',
            matched: ssoMatch.provider,
            description: `Fake ${ssoMatch.provider} SSO popup detected`,
            severity: 'critical',
            weight: 5,
            metadata: {
              provider: ssoMatch.provider,
              indicators: ssoMatch.indicators,
              hasLoginForm: element.hasLoginForm,
              technique: 'sso-popup-spoofing'
            }
          }));
        }
      }
    }

    // 3. Detect fake window controls
    if (dom.windowControls && Array.isArray(dom.windowControls)) {
      for (const control of dom.windowControls) {
        // Window controls (close, minimize, maximize) that aren't real browser controls
        if (control.inPageContent && !control.isRealBrowserControl) {
          findings.push(this.createFinding({
            pattern: 'fake-window-controls',
            matched: `${control.type} button`,
            description: 'Fake window control buttons detected',
            severity: 'medium',
            weight: 2,
            metadata: {
              controlType: control.type,
              position: control.position,
              technique: 'window-control-spoofing'
            }
          }));
        }
      }
    }

    // 4. Detect fake address bar within modal
    if (dom.modalAddressBars && Array.isArray(dom.modalAddressBars)) {
      for (const addressBar of dom.modalAddressBars) {
        // Address bar-like element that's inside a modal, not the real browser address bar
        findings.push(this.createFinding({
          pattern: 'modal-address-bar',
          matched: addressBar.url || 'address bar element',
          description: 'Fake address bar inside modal dialog',
          severity: 'high',
          weight: 4,
          metadata: {
            displayedUrl: addressBar.url,
            insideModal: true,
            technique: 'embedded-address-bar'
          }
        }));
      }
    }

    // 5. Detect window-like styling on non-window elements
    if (dom.shadowedElements && Array.isArray(dom.shadowedElements)) {
      for (const element of dom.shadowedElements) {
        // Elements with window-like box shadows and borders
        if (this.hasWindowLikeStyling(element)) {
          findings.push(this.createFinding({
            pattern: 'window-like-styling',
            matched: element.tagName || 'styled element',
            description: 'Element styled to resemble browser window',
            severity: 'medium',
            weight: 2,
            metadata: {
              boxShadow: element.boxShadow,
              border: element.border,
              borderRadius: element.borderRadius,
              technique: 'window-mimicry'
            }
          }));
        }
      }
    }

    // 6. Detect centered modal with login form (common BitB pattern)
    if (target.hasCenteredLoginModal) {
      findings.push(this.createFinding({
        pattern: 'centered-login-modal',
        matched: 'Centered modal with login form',
        description: 'Centered modal dialog containing login form',
        severity: 'medium',
        weight: 2,
        metadata: {
          technique: 'login-overlay'
        }
      }));
    }

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

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

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

    // Check for fake address bar
    if (element.hasAddressBar) {
      score += 2;
      reasons.push('Contains fake address bar');
    }

    // Check for window controls (close/minimize/maximize buttons)
    if (element.hasWindowControls) {
      score += 2;
      reasons.push('Contains window control buttons');
    }

    // Check for window-like border
    if (element.hasBorder && element.borderStyle === 'window-like') {
      score += 1;
      reasons.push('Has window-like border styling');
    }

    // Check for window-like shadow
    if (element.hasBoxShadow && element.shadowIntensity === 'strong') {
      score += 1;
      reasons.push('Has prominent box shadow (window effect)');
    }

    // Check if element is centered (typical for fake windows)
    if (element.isCentered) {
      score += 1;
      reasons.push('Centered on page (typical popup position)');
    }

    // Check if contains login form
    if (element.hasLoginForm) {
      score += 2;
      reasons.push('Contains login/credential form');
    }

    // Check if has title bar
    if (element.hasTitleBar) {
      score += 1;
      reasons.push('Has title bar element');
    }

    // Check size (typical fake window size)
    if (element.widthPercent > 30 && element.widthPercent < 80) {
      score += 1;
      reasons.push('Size typical of popup window');
    }

    return { score, reasons };
  }

  detectSSOPopupMimicry(element, ssoProviders) {
    for (const provider of ssoProviders) {
      const indicators = [];

      // Check for provider branding in text/images
      if (element.text && this.testPattern(provider.brandPattern, element.text)) {
        indicators.push('Provider branding in text');
      }

      // Check for provider logo
      if (element.hasLogo && element.logoSrc && element.logoSrc.includes(provider.logoKeyword)) {
        indicators.push('Provider logo detected');
      }

      // Check for fake provider URL in fake address bar
      if (element.fakeAddressBarUrl && this.testPattern(provider.urlPattern, element.fakeAddressBarUrl)) {
        indicators.push('Fake provider URL in address bar');
      }

      // Check for provider-specific colors
      if (provider.brandColor && element.primaryColor === provider.brandColor) {
        indicators.push('Provider brand colors');
      }

      // If multiple indicators match, it's likely SSO spoofing
      if (indicators.length >= 2) {
        return {
          provider: provider.name,
          indicators
        };
      }
    }

    return null;
  }

  hasWindowLikeStyling(element) {
    // Check if element has styling that resembles a window
    const hasStrongShadow = element.boxShadow && element.boxShadow.includes('rgba') && element.boxShadow.includes('10px');
    const hasBorder = element.border && element.borderWidth > 0;
    const hasRoundedCorners = element.borderRadius && parseInt(element.borderRadius) > 5;

    return hasStrongShadow && hasBorder && hasRoundedCorners;
  }
}
