/**
 * Security Scanner Service
 *
 * Automated security vulnerability scanner that checks for common security issues:
 * - Authentication bypass attempts
 * - Missing security headers
 * - Rate limiting effectiveness
 * - CSRF protection
 * - SQL injection vulnerabilities
 * - XSS vulnerabilities
 * - Exposed sensitive endpoints
 * - Configuration issues
 *
 * @module services/security-scanner
 */

import { createId } from '@paralleldrive/cuid2';
import { logger } from '@/lib/logger';
import type {
  SecurityScanResult,
  SecurityScanSummary,
  SecurityCheckResult,
  Vulnerability,
  SecurityScannerConfig,
  SecurityCheckCategory,
  SecurityCheckStatus,
  VulnerabilitySeverity,
} from '@/lib/types/security-scanner.types';
import { aiSecurityAnalyzerService, type AISecurityFinding } from './ai-security-analyzer.service';

const SCANNER_VERSION = '1.0.0';

/**
 * Default configuration
 */
const DEFAULT_CONFIG: SecurityScannerConfig = {
  baseUrl: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:9000',
  checkTimeout: 5000, // 5 seconds per check
  maxConcurrent: 3,
  sendAlerts: true,
  alertEmails: ['asimali06@hotmail.com'],
  alertSeverityThreshold: 'medium',
  storeResults: true,
};

/**
 * Security headers to check
 */
const SECURITY_HEADERS = [
  {
    header: 'Strict-Transport-Security',
    expectedPattern: /max-age=\d+/,
    severity: 'high' as VulnerabilitySeverity,
    description: 'HSTS header enforces HTTPS connections',
  },
  {
    header: 'X-Content-Type-Options',
    expectedValue: 'nosniff',
    severity: 'medium' as VulnerabilitySeverity,
    description: 'Prevents MIME type sniffing attacks',
  },
  {
    header: 'X-Frame-Options',
    expectedPattern: /^(DENY|SAMEORIGIN)$/,
    severity: 'medium' as VulnerabilitySeverity,
    description: 'Prevents clickjacking attacks',
  },
  {
    header: 'X-XSS-Protection',
    expectedValue: '1; mode=block',
    severity: 'low' as VulnerabilitySeverity,
    description: 'Legacy XSS protection (CSP is preferred)',
  },
  {
    header: 'Content-Security-Policy',
    expectedPattern: /.+/,
    severity: 'high' as VulnerabilitySeverity,
    description: 'CSP prevents XSS and injection attacks',
  },
  {
    header: 'Referrer-Policy',
    expectedPattern: /^(no-referrer|strict-origin|strict-origin-when-cross-origin)$/,
    severity: 'low' as VulnerabilitySeverity,
    description: 'Controls referrer information sent with requests',
  },
  {
    header: 'Permissions-Policy',
    expectedPattern: /.+/,
    severity: 'low' as VulnerabilitySeverity,
    description: 'Controls browser features and APIs',
  },
];

/**
 * Endpoints to test for authentication and authorization
 */
const AUTH_ENDPOINTS = [
  { path: '/api/user/profile', method: 'GET', requiresAuth: true },
  { path: '/api/user/preferences', method: 'GET', requiresAuth: true },
  { path: '/api/subscriptions/status', method: 'GET', requiresAuth: true },
  { path: '/api/team/members', method: 'GET', requiresAuth: true },
  { path: '/api/notifications', method: 'GET', requiresAuth: true },
  { path: '/api/staff/users', method: 'GET', requiresAuth: true, isStaffOnly: true },
];

/**
 * Endpoints to test for rate limiting
 */
const RATE_LIMIT_ENDPOINTS = [
  { path: '/api/auth/send-otp', method: 'POST', shouldBeRateLimited: true },
  { path: '/api/auth/verify-otp', method: 'POST', shouldBeRateLimited: true },
  { path: '/api/contact/submit', method: 'POST', shouldBeRateLimited: true },
  { path: '/api/demo/book', method: 'POST', shouldBeRateLimited: true },
];

/**
 * SQL injection test payloads
 */
const SQL_INJECTION_PAYLOADS = [
  "' OR '1'='1",
  "'; DROP TABLE users; --",
  "1'; SELECT * FROM users--",
  "admin'--",
  "1 UNION SELECT * FROM users",
];

/**
 * XSS test payloads
 */
const XSS_PAYLOADS = [
  '<script>alert("xss")</script>',
  'javascript:alert(1)',
  '<img src=x onerror=alert(1)>',
  '"><script>alert(1)</script>',
  "';alert(1)//",
];

/**
 * Security Scanner Service
 */
export class SecurityScannerService {
  private config: SecurityScannerConfig;
  private checks: SecurityCheckResult[] = [];
  private vulnerabilities: Vulnerability[] = [];

  constructor(config: Partial<SecurityScannerConfig> = {}) {
    this.config = { ...DEFAULT_CONFIG, ...config };
  }

  /**
   * Run a complete security scan
   */
  async runFullScan(): Promise<SecurityScanResult> {
    const scanId = createId();
    const startedAt = new Date();

    logger.info('Starting security scan', { scanId });

    this.checks = [];
    this.vulnerabilities = [];

    try {
      // Run all security checks in categories
      await this.runSecurityHeaderChecks();
      await this.runAuthenticationChecks();
      await this.runRateLimitChecks();
      await this.runCSRFChecks();
      await this.runEndpointSecurityChecks();
      await this.runConfigurationChecks();
      await this.runInjectionChecks();
      await this.runDataExposureChecks();

      // Run AI-powered code analysis (Claude Opus 4.5)
      await this.runAICodeAnalysis();

      const completedAt = new Date();
      const duration = completedAt.getTime() - startedAt.getTime();

      const summary = this.calculateSummary();

      const result: SecurityScanResult = {
        scanId,
        startedAt,
        completedAt,
        duration,
        summary,
        checks: this.checks,
        vulnerabilities: this.vulnerabilities,
        environment: this.detectEnvironment(),
        baseUrl: this.config.baseUrl,
        scannerVersion: SCANNER_VERSION,
      };

      logger.info('Security scan completed', {
        scanId,
        duration,
        securityScore: summary.securityScore,
        riskLevel: summary.riskLevel,
        vulnerabilities: summary.vulnerabilities,
      });

      return result;
    } catch (error) {
      logger.error('Security scan failed', {
        scanId,
        error: error instanceof Error ? error.message : String(error),
      });
      throw error;
    }
  }

  /**
   * Run AI-powered code analysis using Claude
   */
  private async runAICodeAnalysis(): Promise<void> {
    logger.info('Running AI-powered code analysis with Claude');
    const startTime = Date.now();

    try {
      const aiAnalysis = await aiSecurityAnalyzerService.runFullAnalysis();

      // Add AI analysis as a check
      this.addCheck({
        id: 'ai-code-analysis',
        name: 'AI Code Security Analysis (Claude)',
        category: 'code_analysis' as SecurityCheckCategory,
        status: aiAnalysis.findings.length > 0 ? 'warning' : 'pass',
        severity: aiAnalysis.summary.overallRisk === 'critical' ? 'critical' :
                  aiAnalysis.summary.overallRisk === 'high' ? 'high' :
                  aiAnalysis.summary.overallRisk === 'medium' ? 'medium' : 'low',
        description: 'AI-powered analysis of codebase for security vulnerabilities',
        details: `Analyzed ${aiAnalysis.areasAnalyzed.length} areas. Found ${aiAnalysis.findings.length} potential issues. AI Confidence: ${aiAnalysis.summary.aiConfidence}%`,
        duration: Date.now() - startTime,
      });

      // Convert AI findings to vulnerabilities
      for (const finding of aiAnalysis.findings) {
        this.addVulnerabilityFromAIFinding(finding);
      }

      // Add AI recommendations as info checks
      for (const recommendation of aiAnalysis.recommendations) {
        this.addCheck({
          id: `ai-recommendation-${createId()}`,
          name: 'AI Security Recommendation',
          category: 'code_analysis' as SecurityCheckCategory,
          status: 'info' as SecurityCheckStatus,
          severity: 'info',
          description: recommendation,
          details: 'Recommendation from AI analysis',
          duration: 0,
        });
      }

      logger.info('AI code analysis completed', {
        analysisId: aiAnalysis.analysisId,
        findingsCount: aiAnalysis.findings.length,
        aiConfidence: aiAnalysis.summary.aiConfidence,
        areasAnalyzed: aiAnalysis.areasAnalyzed,
      });
    } catch (error) {
      logger.error('AI code analysis failed', {
        error: error instanceof Error ? error.message : String(error),
      });

      this.addCheck({
        id: 'ai-code-analysis-error',
        name: 'AI Code Security Analysis',
        category: 'code_analysis' as SecurityCheckCategory,
        status: 'error',
        severity: 'medium',
        description: 'AI-powered code analysis failed',
        details: error instanceof Error ? error.message : String(error),
        duration: Date.now() - startTime,
      });
    }
  }

  /**
   * Convert AI finding to vulnerability
   */
  private addVulnerabilityFromAIFinding(finding: AISecurityFinding): void {
    // Map AI severity to vulnerability severity
    const severityMap: Record<string, VulnerabilitySeverity> = {
      critical: 'critical',
      high: 'high',
      medium: 'medium',
      low: 'low',
      info: 'info',
    };

    // Map AI category to security category
    const categoryMap: Record<string, string> = {
      'Authentication': 'authentication',
      'Authorization': 'authorization',
      'Injection': 'injection',
      'Data Exposure': 'data_exposure',
      'Configuration': 'configuration',
      'Cryptographic': 'cryptographic',
      'Session': 'session',
      'XSS': 'xss',
      'CSRF': 'csrf',
      'SSRF': 'ssrf',
    };

    const severity = severityMap[finding.severity] || 'medium';
    const category = categoryMap[finding.category] || 'code_analysis';

    this.vulnerabilities.push({
      id: finding.id,
      title: `[AI] ${finding.title}`,
      severity,
      category: category as SecurityCheckCategory,
      description: `${finding.description}${finding.file ? ` (File: ${finding.file}${finding.line ? `:${finding.line}` : ''})` : ''}`,
      remediation: finding.remediation,
      affectedResources: finding.file ? [finding.file] : ['Codebase'],
      firstDetected: new Date(),
      lastSeen: new Date(),
      cweId: finding.cweId,
    });

    // Also add as a check for tracking
    this.addCheck({
      id: `ai-finding-${finding.id}`,
      name: `[AI] ${finding.title}`,
      category: category as SecurityCheckCategory,
      status: 'fail',
      severity,
      description: finding.description,
      details: `Confidence: ${finding.confidence}. ${finding.remediation}`,
      affectedResource: finding.file || 'Codebase',
      duration: 0,
    });
  }

  /**
   * Check security headers
   */
  private async runSecurityHeaderChecks(): Promise<void> {
    logger.debug('Running security header checks');

    try {
      const response = await this.fetchWithTimeout(this.config.baseUrl, {
        method: 'GET',
      });

      for (const headerConfig of SECURITY_HEADERS) {
        const startTime = Date.now();
        const headerValue = response.headers.get(headerConfig.header);

        let status: SecurityCheckStatus = 'pass';
        let details = '';

        if (!headerValue) {
          status = 'fail';
          details = `Missing ${headerConfig.header} header`;
          this.addVulnerability({
            title: `Missing Security Header: ${headerConfig.header}`,
            severity: headerConfig.severity,
            category: 'headers',
            description: headerConfig.description,
            remediation: `Add the ${headerConfig.header} header to your server responses`,
            affectedResources: [this.config.baseUrl],
          });
        } else if (headerConfig.expectedValue && headerValue !== headerConfig.expectedValue) {
          status = 'warning';
          details = `Expected "${headerConfig.expectedValue}", got "${headerValue}"`;
        } else if (headerConfig.expectedPattern && !headerConfig.expectedPattern.test(headerValue)) {
          status = 'warning';
          details = `Header value "${headerValue}" does not match expected pattern`;
        }

        this.addCheck({
          id: `header-${headerConfig.header.toLowerCase()}`,
          name: `Security Header: ${headerConfig.header}`,
          category: 'headers',
          status,
          severity: headerConfig.severity,
          description: headerConfig.description,
          details,
          affectedResource: this.config.baseUrl,
          duration: Date.now() - startTime,
        });
      }
    } catch (error) {
      this.addCheck({
        id: 'header-check-error',
        name: 'Security Headers Check',
        category: 'headers',
        status: 'error',
        severity: 'high',
        description: 'Unable to check security headers',
        details: error instanceof Error ? error.message : String(error),
        duration: 0,
      });
    }
  }

  /**
   * Check authentication endpoints
   */
  private async runAuthenticationChecks(): Promise<void> {
    logger.debug('Running authentication checks');

    for (const endpoint of AUTH_ENDPOINTS) {
      const startTime = Date.now();
      const fullUrl = `${this.config.baseUrl}${endpoint.path}`;

      try {
        // Try accessing without authentication
        const response = await this.fetchWithTimeout(fullUrl, {
          method: endpoint.method,
          headers: {
            'Content-Type': 'application/json',
          },
        });

        const status = response.status;
        let checkStatus: SecurityCheckStatus = 'pass';
        let details = '';

        // Protected endpoints should return 401 or 403 without auth
        if (endpoint.requiresAuth && status !== 401 && status !== 403) {
          checkStatus = 'fail';
          details = `Endpoint returned ${status} without authentication (expected 401/403)`;

          this.addVulnerability({
            title: `Authentication Bypass: ${endpoint.path}`,
            severity: 'critical',
            category: 'authentication',
            description: `Protected endpoint ${endpoint.path} is accessible without authentication`,
            remediation: 'Ensure proper authentication middleware is applied to this endpoint',
            affectedResources: [endpoint.path],
          });
        } else if (endpoint.requiresAuth) {
          details = `Correctly returns ${status} without authentication`;
        }

        this.addCheck({
          id: `auth-${endpoint.path.replace(/\//g, '-')}`,
          name: `Auth Check: ${endpoint.path}`,
          category: 'authentication',
          status: checkStatus,
          severity: 'critical',
          description: `Verify ${endpoint.path} requires authentication`,
          details,
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      } catch (error) {
        this.addCheck({
          id: `auth-${endpoint.path.replace(/\//g, '-')}`,
          name: `Auth Check: ${endpoint.path}`,
          category: 'authentication',
          status: 'error',
          severity: 'high',
          description: `Unable to check authentication for ${endpoint.path}`,
          details: error instanceof Error ? error.message : String(error),
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      }
    }
  }

  /**
   * Check rate limiting
   */
  private async runRateLimitChecks(): Promise<void> {
    logger.debug('Running rate limit checks');

    for (const endpoint of RATE_LIMIT_ENDPOINTS) {
      const startTime = Date.now();
      const fullUrl = `${this.config.baseUrl}${endpoint.path}`;

      try {
        // Make a single request and check for rate limit headers
        const response = await this.fetchWithTimeout(fullUrl, {
          method: endpoint.method,
          headers: {
            'Content-Type': 'application/json',
          },
          body: endpoint.method !== 'GET' ? JSON.stringify({ test: true }) : undefined,
        });

        const hasRateLimitHeaders =
          response.headers.has('X-RateLimit-Limit') ||
          response.headers.has('RateLimit-Limit') ||
          response.headers.has('X-Rate-Limit-Limit') ||
          response.headers.has('Retry-After');

        // Also check if we got rate limited (429)
        const isRateLimited = response.status === 429;

        let checkStatus: SecurityCheckStatus = 'pass';
        let details = '';

        if (endpoint.shouldBeRateLimited && !hasRateLimitHeaders && !isRateLimited) {
          checkStatus = 'warning';
          details = 'No rate limit headers detected (may still be rate limited server-side)';
        } else if (hasRateLimitHeaders || isRateLimited) {
          details = 'Rate limiting is active';
          if (response.headers.get('X-RateLimit-Limit')) {
            details += ` (Limit: ${response.headers.get('X-RateLimit-Limit')})`;
          }
        }

        this.addCheck({
          id: `rate-limit-${endpoint.path.replace(/\//g, '-')}`,
          name: `Rate Limit: ${endpoint.path}`,
          category: 'rate_limiting',
          status: checkStatus,
          severity: 'medium',
          description: `Verify rate limiting on ${endpoint.path}`,
          details,
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      } catch (error) {
        this.addCheck({
          id: `rate-limit-${endpoint.path.replace(/\//g, '-')}`,
          name: `Rate Limit: ${endpoint.path}`,
          category: 'rate_limiting',
          status: 'error',
          severity: 'medium',
          description: `Unable to check rate limiting for ${endpoint.path}`,
          details: error instanceof Error ? error.message : String(error),
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      }
    }
  }

  /**
   * Check CSRF protection
   */
  private async runCSRFChecks(): Promise<void> {
    logger.debug('Running CSRF checks');

    const csrfEndpoints = [
      '/api/user/preferences',
      '/api/contact/submit',
      '/api/auth/logout',
    ];

    for (const endpoint of csrfEndpoints) {
      const startTime = Date.now();
      const fullUrl = `${this.config.baseUrl}${endpoint}`;

      try {
        // Try POST without CSRF token
        const response = await this.fetchWithTimeout(fullUrl, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ test: true }),
        });

        let checkStatus: SecurityCheckStatus = 'pass';
        let details = '';

        // Should reject requests without CSRF token (400 or 403)
        if (response.status !== 400 && response.status !== 403 && response.status !== 401) {
          checkStatus = 'warning';
          details = `Endpoint returned ${response.status} without CSRF token`;
        } else {
          details = `Correctly rejects requests without CSRF token (${response.status})`;
        }

        this.addCheck({
          id: `csrf-${endpoint.replace(/\//g, '-')}`,
          name: `CSRF Protection: ${endpoint}`,
          category: 'csrf',
          status: checkStatus,
          severity: 'high',
          description: `Verify CSRF protection on ${endpoint}`,
          details,
          affectedResource: endpoint,
          duration: Date.now() - startTime,
        });
      } catch (error) {
        this.addCheck({
          id: `csrf-${endpoint.replace(/\//g, '-')}`,
          name: `CSRF Protection: ${endpoint}`,
          category: 'csrf',
          status: 'error',
          severity: 'high',
          description: `Unable to check CSRF protection for ${endpoint}`,
          details: error instanceof Error ? error.message : String(error),
          affectedResource: endpoint,
          duration: Date.now() - startTime,
        });
      }
    }
  }

  /**
   * Check for exposed sensitive endpoints
   */
  private async runEndpointSecurityChecks(): Promise<void> {
    logger.debug('Running endpoint security checks');

    const sensitiveEndpoints = [
      { path: '/.env', shouldBe404: true },
      { path: '/.git/config', shouldBe404: true },
      { path: '/api/.env', shouldBe404: true },
      { path: '/debug', shouldBe404: true },
      { path: '/api/debug', shouldRequireAuth: true },
      { path: '/phpinfo.php', shouldBe404: true },
      { path: '/wp-admin', shouldBe404: true },
      { path: '/admin', shouldRequireAuth: true },
      { path: '/.well-known/security.txt', shouldExist: false },
      { path: '/robots.txt', shouldExist: true },
    ];

    for (const endpoint of sensitiveEndpoints) {
      const startTime = Date.now();
      const fullUrl = `${this.config.baseUrl}${endpoint.path}`;

      try {
        const response = await this.fetchWithTimeout(fullUrl, {
          method: 'GET',
        });

        let checkStatus: SecurityCheckStatus = 'pass';
        let details = '';

        if (endpoint.shouldBe404 && response.status !== 404) {
          checkStatus = 'fail';
          details = `Sensitive path ${endpoint.path} is accessible (status: ${response.status})`;

          this.addVulnerability({
            title: `Exposed Sensitive Path: ${endpoint.path}`,
            severity: 'critical',
            category: 'data_exposure',
            description: `Sensitive file or path ${endpoint.path} is accessible`,
            remediation: 'Block access to sensitive paths in your web server configuration',
            affectedResources: [endpoint.path],
          });
        } else if (endpoint.shouldBe404) {
          details = `Correctly returns 404 for ${endpoint.path}`;
        }

        if (endpoint.shouldRequireAuth && response.status !== 401 && response.status !== 403 && response.status !== 404) {
          checkStatus = 'warning';
          details = `Admin path accessible without auth (status: ${response.status})`;
        }

        this.addCheck({
          id: `endpoint-${endpoint.path.replace(/[\/\.]/g, '-')}`,
          name: `Endpoint Security: ${endpoint.path}`,
          category: 'endpoints',
          status: checkStatus,
          severity: endpoint.shouldBe404 ? 'critical' : 'medium',
          description: `Check security of ${endpoint.path}`,
          details,
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      } catch (error) {
        // Network errors are expected for non-existent paths
        this.addCheck({
          id: `endpoint-${endpoint.path.replace(/[\/\.]/g, '-')}`,
          name: `Endpoint Security: ${endpoint.path}`,
          category: 'endpoints',
          status: endpoint.shouldBe404 ? 'pass' : 'error',
          severity: 'medium',
          description: `Check security of ${endpoint.path}`,
          details: endpoint.shouldBe404 ? 'Path not accessible (good)' : String(error),
          affectedResource: endpoint.path,
          duration: Date.now() - startTime,
        });
      }
    }
  }

  /**
   * Check configuration security
   */
  private async runConfigurationChecks(): Promise<void> {
    logger.debug('Running configuration checks');
    const startTime = Date.now();

    // Check if debug mode is exposed
    try {
      const response = await this.fetchWithTimeout(`${this.config.baseUrl}/api/health`, {
        method: 'GET',
      });

      if (response.ok) {
        const data = await response.json();

        // Check if sensitive info is exposed
        const sensitiveFields = ['database', 'connectionString', 'apiKey', 'secret', 'password'];
        const exposedFields = sensitiveFields.filter(
          (field) => JSON.stringify(data).toLowerCase().includes(field.toLowerCase())
        );

        if (exposedFields.length > 0) {
          this.addVulnerability({
            title: 'Sensitive Information in Health Endpoint',
            severity: 'high',
            category: 'configuration',
            description: `Health endpoint may expose sensitive information: ${exposedFields.join(', ')}`,
            remediation: 'Remove sensitive information from health check responses',
            affectedResources: ['/api/health'],
          });
        }

        this.addCheck({
          id: 'config-health-exposure',
          name: 'Health Endpoint Information Exposure',
          category: 'configuration',
          status: exposedFields.length > 0 ? 'fail' : 'pass',
          severity: 'high',
          description: 'Check if health endpoint exposes sensitive information',
          details: exposedFields.length > 0
            ? `Found potentially sensitive fields: ${exposedFields.join(', ')}`
            : 'No sensitive information detected',
          affectedResource: '/api/health',
          duration: Date.now() - startTime,
        });
      }
    } catch (error) {
      this.addCheck({
        id: 'config-health-exposure',
        name: 'Health Endpoint Information Exposure',
        category: 'configuration',
        status: 'error',
        severity: 'medium',
        description: 'Unable to check health endpoint',
        details: error instanceof Error ? error.message : String(error),
        duration: Date.now() - startTime,
      });
    }

    // Check for error page information disclosure
    try {
      const response = await this.fetchWithTimeout(
        `${this.config.baseUrl}/api/nonexistent-endpoint-${Date.now()}`,
        { method: 'GET' }
      );

      if (response.status === 500) {
        const text = await response.text();
        const exposesStackTrace = text.includes('at ') && text.includes('.ts:') || text.includes('.js:');

        this.addCheck({
          id: 'config-error-disclosure',
          name: 'Error Page Information Disclosure',
          category: 'configuration',
          status: exposesStackTrace ? 'fail' : 'pass',
          severity: 'medium',
          description: 'Check if error pages expose stack traces',
          details: exposesStackTrace
            ? 'Error page exposes stack trace information'
            : 'Error page does not expose sensitive information',
          duration: Date.now() - startTime,
        });

        if (exposesStackTrace) {
          this.addVulnerability({
            title: 'Stack Trace Exposure in Error Pages',
            severity: 'medium',
            category: 'configuration',
            description: 'Error pages expose stack trace information to users',
            remediation: 'Configure custom error pages that do not expose stack traces in production',
            affectedResources: ['Error pages'],
          });
        }
      }
    } catch {
      // Expected for non-existent endpoints
    }
  }

  /**
   * Check for injection vulnerabilities
   */
  private async runInjectionChecks(): Promise<void> {
    logger.debug('Running injection vulnerability checks');

    // Test a search or query endpoint if available
    const testEndpoints = ['/api/search', '/api/users/search', '/en/blog'];

    for (const endpoint of testEndpoints) {
      const startTime = Date.now();

      for (const payload of SQL_INJECTION_PAYLOADS.slice(0, 2)) {
        try {
          const response = await this.fetchWithTimeout(
            `${this.config.baseUrl}${endpoint}?q=${encodeURIComponent(payload)}`,
            { method: 'GET' }
          );

          // Check response for SQL error indicators
          const text = await response.text();
          const sqlErrorIndicators = [
            'SQL syntax',
            'mysql_fetch',
            'ORA-',
            'PostgreSQL',
            'SQLite3::',
            'SQLSTATE',
            'syntax error',
            'unclosed quotation',
          ];

          const foundSqlError = sqlErrorIndicators.some((indicator) =>
            text.toLowerCase().includes(indicator.toLowerCase())
          );

          if (foundSqlError) {
            this.addVulnerability({
              title: `Potential SQL Injection: ${endpoint}`,
              severity: 'critical',
              category: 'injection',
              description: `Endpoint ${endpoint} may be vulnerable to SQL injection`,
              remediation: 'Use parameterized queries and input validation',
              affectedResources: [endpoint],
            });

            this.addCheck({
              id: `injection-sql-${endpoint.replace(/\//g, '-')}`,
              name: `SQL Injection: ${endpoint}`,
              category: 'injection',
              status: 'fail',
              severity: 'critical',
              description: 'Test for SQL injection vulnerability',
              details: 'SQL error messages detected in response',
              affectedResource: endpoint,
              duration: Date.now() - startTime,
            });
            break;
          }
        } catch {
          // Expected for non-existent endpoints
        }
      }
    }

    // XSS reflection check
    for (const payload of XSS_PAYLOADS.slice(0, 2)) {
      try {
        const response = await this.fetchWithTimeout(
          `${this.config.baseUrl}/en?search=${encodeURIComponent(payload)}`,
          { method: 'GET' }
        );

        const text = await response.text();

        // Check if payload is reflected without encoding
        if (text.includes(payload)) {
          this.addVulnerability({
            title: 'Potential Reflected XSS',
            severity: 'high',
            category: 'xss',
            description: 'User input may be reflected without proper encoding',
            remediation: 'Ensure all user input is properly HTML encoded before rendering',
            affectedResources: ['Search functionality'],
          });
          break;
        }
      } catch {
        // Expected for unavailable endpoints
      }
    }
  }

  /**
   * Check for data exposure vulnerabilities
   */
  private async runDataExposureChecks(): Promise<void> {
    logger.debug('Running data exposure checks');
    const startTime = Date.now();

    // Check for exposed API documentation
    const docPaths = ['/api-docs', '/swagger', '/swagger.json', '/openapi.json', '/graphql'];

    for (const docPath of docPaths) {
      try {
        const response = await this.fetchWithTimeout(`${this.config.baseUrl}${docPath}`, {
          method: 'GET',
        });

        if (response.ok) {
          this.addCheck({
            id: `exposure-${docPath.replace(/\//g, '-')}`,
            name: `API Documentation: ${docPath}`,
            category: 'data_exposure',
            status: 'warning',
            severity: 'low',
            description: `Check if ${docPath} is publicly accessible`,
            details: 'API documentation is publicly accessible',
            affectedResource: docPath,
            duration: Date.now() - startTime,
          });
        }
      } catch {
        // Expected for non-existent paths
      }
    }

    // Check for source map exposure
    try {
      const mainPage = await this.fetchWithTimeout(this.config.baseUrl, { method: 'GET' });
      const html = await mainPage.text();

      // Look for source map references
      const sourceMapMatch = html.match(/sourceMappingURL=([^\s"']+)/);
      if (sourceMapMatch) {
        this.addCheck({
          id: 'exposure-sourcemaps',
          name: 'Source Map Exposure',
          category: 'data_exposure',
          status: 'warning',
          severity: 'low',
          description: 'Check if source maps are exposed in production',
          details: 'Source maps may be accessible',
          duration: Date.now() - startTime,
        });
      }
    } catch {
      // Page not accessible
    }
  }

  /**
   * Add a check result
   */
  private addCheck(check: Omit<SecurityCheckResult, 'timestamp'>): void {
    this.checks.push({
      ...check,
      timestamp: new Date(),
    });
  }

  /**
   * Add a vulnerability
   */
  private addVulnerability(vuln: Omit<Vulnerability, 'id' | 'firstDetected' | 'lastSeen'>): void {
    this.vulnerabilities.push({
      ...vuln,
      id: createId(),
      firstDetected: new Date(),
      lastSeen: new Date(),
    });
  }

  /**
   * Calculate scan summary
   */
  private calculateSummary(): SecurityScanSummary {
    const passed = this.checks.filter((c) => c.status === 'pass').length;
    const failed = this.checks.filter((c) => c.status === 'fail').length;
    const warnings = this.checks.filter((c) => c.status === 'warning').length;
    const errors = this.checks.filter((c) => c.status === 'error').length;
    const skipped = this.checks.filter((c) => c.status === 'skipped').length;

    const vulnCounts = {
      critical: this.vulnerabilities.filter((v) => v.severity === 'critical').length,
      high: this.vulnerabilities.filter((v) => v.severity === 'high').length,
      medium: this.vulnerabilities.filter((v) => v.severity === 'medium').length,
      low: this.vulnerabilities.filter((v) => v.severity === 'low').length,
      info: this.vulnerabilities.filter((v) => v.severity === 'info').length,
    };

    // Calculate security score (0-100)
    const totalChecks = this.checks.length || 1;
    const baseScore = (passed / totalChecks) * 100;

    // Deduct points for vulnerabilities
    const vulnPenalty =
      vulnCounts.critical * 20 +
      vulnCounts.high * 10 +
      vulnCounts.medium * 5 +
      vulnCounts.low * 2 +
      vulnCounts.info * 0;

    const securityScore = Math.max(0, Math.min(100, Math.round(baseScore - vulnPenalty)));

    // Determine risk level
    let riskLevel: SecurityScanSummary['riskLevel'] = 'minimal';
    if (vulnCounts.critical > 0) {
      riskLevel = 'critical';
    } else if (vulnCounts.high > 0) {
      riskLevel = 'high';
    } else if (vulnCounts.medium > 0 || failed > 3) {
      riskLevel = 'medium';
    } else if (vulnCounts.low > 0 || warnings > 3) {
      riskLevel = 'low';
    }

    return {
      totalChecks,
      passed,
      failed,
      warnings,
      errors,
      skipped,
      vulnerabilities: vulnCounts,
      securityScore,
      riskLevel,
    };
  }

  /**
   * Detect environment
   */
  private detectEnvironment(): 'development' | 'staging' | 'production' {
    const url = this.config.baseUrl.toLowerCase();
    if (url.includes('localhost') || url.includes('127.0.0.1')) {
      return 'development';
    }
    if (url.includes('staging') || url.includes('dev.') || url.includes('test.')) {
      return 'staging';
    }
    return 'production';
  }

  /**
   * Fetch with timeout
   */
  private async fetchWithTimeout(
    url: string,
    options: RequestInit = {}
  ): Promise<Response> {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.config.checkTimeout);

    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal,
      });
      return response;
    } finally {
      clearTimeout(timeoutId);
    }
  }
}

// Export singleton
export const securityScannerService = new SecurityScannerService();
