/**
 * 质量保证系统
 * 为AI自动生成打下基石
 */

class QualityAssurance {
  constructor() {
    this.validators = {
      syntax: this.validateSyntax.bind(this),
      types: this.validateTypes.bind(this),
      imports: this.validateImports.bind(this),
      business: this.validateBusinessLogic.bind(this),
      performance: this.validatePerformance.bind(this),
      security: this.validateSecurity.bind(this)
    };
    
    this.fixers = {
      syntax: this.fixSyntaxErrors.bind(this),
      types: this.fixTypeErrors.bind(this),
      imports: this.fixImportErrors.bind(this),
      business: this.fixBusinessLogicErrors.bind(this)
    };
    
    this.metrics = {
      complexity: this.calculateComplexity.bind(this),
      maintainability: this.calculateMaintainability.bind(this),
      testability: this.calculateTestability.bind(this),
      performance: this.calculatePerformance.bind(this)
    };
  }
  
  /**
   * 执行完整的质量检查
   */
  async performQualityCheck(code, context = {}) {
    const results = {
      overall: 'pass',
      validations: {},
      fixes: {},
      metrics: {},
      recommendations: [],
      errors: [],
      warnings: []
    };
    
    console.log('🛡️ 开始质量检查...');
    
    // 执行所有验证
    for (const [type, validator] of Object.entries(this.validators)) {
      try {
        console.log(`  🔍 执行${type}验证...`);
        const validation = await validator(code, context);
        results.validations[type] = validation;
        
        if (validation.errors.length > 0) {
          results.errors.push(...validation.errors);
          results.overall = 'fail';
        }
        
        if (validation.warnings.length > 0) {
          results.warnings.push(...validation.warnings);
        }
        
        console.log(`  ✅ ${type}验证完成: ${validation.errors.length}个错误, ${validation.warnings.length}个警告`);
      } catch (error) {
        console.error(`  ❌ ${type}验证失败:`, error.message);
        results.errors.push({
          type,
          message: error.message,
          stack: error.stack
        });
        results.overall = 'fail';
      }
    }
    
    // 计算质量指标
    for (const [type, calculator] of Object.entries(this.metrics)) {
      try {
        results.metrics[type] = calculator(code, context);
      } catch (error) {
        console.error(`  ❌ ${type}指标计算失败:`, error.message);
      }
    }
    
    // 生成建议
    results.recommendations = this.generateRecommendations(results);
    
    console.log(`🎯 质量检查完成: ${results.overall.toUpperCase()}`);
    return results;
  }
  
  /**
   * 自动修复代码问题
   */
  async autoFix(code, qualityResults) {
    let fixedCode = code;
    const fixes = [];
    
    console.log('🔧 开始自动修复...');
    
    // 修复语法错误
    if (qualityResults.validations.syntax?.errors.length > 0) {
      const syntaxFixes = await this.fixers.syntax(fixedCode, qualityResults.validations.syntax);
      fixedCode = syntaxFixes.code;
      fixes.push(...syntaxFixes.fixes);
    }
    
    // 修复类型错误
    if (qualityResults.validations.types?.errors.length > 0) {
      const typeFixes = await this.fixers.types(fixedCode, qualityResults.validations.types);
      fixedCode = typeFixes.code;
      fixes.push(...typeFixes.fixes);
    }
    
    // 修复导入错误
    if (qualityResults.validations.imports?.errors.length > 0) {
      const importFixes = await this.fixers.imports(fixedCode, qualityResults.validations.imports);
      fixedCode = importFixes.code;
      fixes.push(...importFixes.fixes);
    }
    
    // 修复业务逻辑错误
    if (qualityResults.validations.business?.errors.length > 0) {
      const businessFixes = await this.fixers.business(fixedCode, qualityResults.validations.business);
      fixedCode = businessFixes.code;
      fixes.push(...businessFixes.fixes);
    }
    
    console.log(`✅ 自动修复完成: ${fixes.length}个修复`);
    
    return {
      code: fixedCode,
      fixes,
      summary: {
        totalFixes: fixes.length,
        fixedTypes: [...new Set(fixes.map(f => f.type))]
      }
    };
  }
  
  /**
   * 验证语法
   */
  async validateSyntax(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查方括号错误
    const bracketErrors = this.findBracketErrors(code);
    errors.push(...bracketErrors);
    
    // 检查重复前缀
    const prefixErrors = this.findPrefixErrors(code);
    errors.push(...prefixErrors);
    
    // 检查语法错误
    const syntaxErrors = this.findSyntaxErrors(code);
    errors.push(...syntaxErrors);
    
    // 检查代码风格
    const styleWarnings = this.findStyleWarnings(code);
    warnings.push(...styleWarnings);
    
    return { errors, warnings };
  }
  
  /**
   * 验证类型
   */
  async validateTypes(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查类型声明
    const typeErrors = this.findTypeErrors(code);
    errors.push(...typeErrors);
    
    // 检查类型使用
    const usageWarnings = this.findTypeUsageWarnings(code);
    warnings.push(...usageWarnings);
    
    return { errors, warnings };
  }
  
  /**
   * 验证导入
   */
  async validateImports(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查缺失的导入
    const missingImports = this.findMissingImports(code);
    errors.push(...missingImports);
    
    // 检查未使用的导入
    const unusedImports = this.findUnusedImports(code);
    warnings.push(...unusedImports);
    
    return { errors, warnings };
  }
  
  /**
   * 验证业务逻辑
   */
  async validateBusinessLogic(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查业务逻辑完整性
    const businessErrors = this.findBusinessLogicErrors(code);
    errors.push(...businessErrors);
    
    // 检查业务规则
    const ruleWarnings = this.findBusinessRuleWarnings(code);
    warnings.push(...ruleWarnings);
    
    return { errors, warnings };
  }
  
  /**
   * 验证性能
   */
  async validatePerformance(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查性能问题
    const performanceIssues = this.findPerformanceIssues(code);
    warnings.push(...performanceIssues);
    
    return { errors, warnings };
  }
  
  /**
   * 验证安全性
   */
  async validateSecurity(code, context) {
    const errors = [];
    const warnings = [];
    
    // 检查安全问题
    const securityIssues = this.findSecurityIssues(code);
    errors.push(...securityIssues);
    
    return { errors, warnings };
  }
  
  // 错误检测方法
  findBracketErrors(code) {
    const errors = [];
    const lines = code.split('\n');
    
    lines.forEach((line, index) => {
      if (line.includes(']') && !line.includes('[')) {
        // 检查是否是函数调用中的方括号错误
        if (line.match(/\w+\]/)) {
          errors.push({
            type: 'syntax',
            message: '方括号错误: 应该是圆括号',
            line: index + 1,
            code: line.trim(),
            severity: 'error'
          });
        }
      }
    });
    
    return errors;
  }
  
  findPrefixErrors(code) {
    const errors = [];
    const lines = code.split('\n');
    
    lines.forEach((line, index) => {
      if (line.includes('BusinessBusinessException')) {
        errors.push({
          type: 'syntax',
          message: '重复的Business前缀',
          line: index + 1,
          code: line.trim(),
          severity: 'error'
        });
      }
    });
    
    return errors;
  }
  
  findSyntaxErrors(code) {
    const errors = [];
    const lines = code.split('\n');
    
    lines.forEach((line, index) => {
      // 检查等号错误
      if (line.includes('====')) {
        errors.push({
          type: 'syntax',
          message: '重复的等号',
          line: index + 1,
          code: line.trim(),
          severity: 'error'
        });
      }
      
      // 检查括号不匹配
      const openParens = (line.match(/\(/g) || []).length;
      const closeParens = (line.match(/\)/g) || []).length;
      const openBrackets = (line.match(/\[/g) || []).length;
      const closeBrackets = (line.match(/\]/g) || []).length;
      
      if (openParens !== closeParens) {
        errors.push({
          type: 'syntax',
          message: '括号不匹配',
          line: index + 1,
          code: line.trim(),
          severity: 'error'
        });
      }
      
      if (openBrackets !== closeBrackets) {
        errors.push({
          type: 'syntax',
          message: '方括号不匹配',
          line: index + 1,
          code: line.trim(),
          severity: 'error'
        });
      }
    });
    
    return errors;
  }
  
  findStyleWarnings(code) {
    const warnings = [];
    const lines = code.split('\n');
    
    lines.forEach((line, index) => {
      // 检查行长度
      if (line.length > 120) {
        warnings.push({
          type: 'style',
          message: '行长度超过120字符',
          line: index + 1,
          code: line.trim(),
          severity: 'warning'
        });
      }
      
      // 检查尾随空格
      if (line.endsWith(' ')) {
        warnings.push({
          type: 'style',
          message: '尾随空格',
          line: index + 1,
          code: line.trim(),
          severity: 'warning'
        });
      }
    });
    
    return warnings;
  }
  
  findTypeErrors(code) {
    const errors = [];
    // 类型错误检测逻辑
    return errors;
  }
  
  findTypeUsageWarnings(code) {
    const warnings = [];
    // 类型使用警告检测逻辑
    return warnings;
  }
  
  findMissingImports(code) {
    const errors = [];
    const lines = code.split('\n');
    
    // 检查使用的类是否已导入
    const usedClasses = this.extractUsedClasses(code);
    const importedClasses = this.extractImportedClasses(code);
    
    usedClasses.forEach(className => {
      if (!importedClasses.includes(className)) {
        errors.push({
          type: 'import',
          message: `缺失导入: ${className}`,
          line: -1,
          code: '',
          severity: 'error'
        });
      }
    });
    
    return errors;
  }
  
  findUnusedImports(code) {
    const warnings = [];
    // 未使用导入检测逻辑
    return warnings;
  }
  
  findBusinessLogicErrors(code) {
    const errors = [];
    // 业务逻辑错误检测逻辑
    return errors;
  }
  
  findBusinessRuleWarnings(code) {
    const warnings = [];
    // 业务规则警告检测逻辑
    return warnings;
  }
  
  findPerformanceIssues(code) {
    const warnings = [];
    // 性能问题检测逻辑
    return warnings;
  }
  
  findSecurityIssues(code) {
    const errors = [];
    // 安全问题检测逻辑
    return errors;
  }
  
  // 修复方法
  async fixSyntaxErrors(code, validation) {
    let fixedCode = code;
    const fixes = [];
    
    validation.errors.forEach(error => {
      if (error.message.includes('方括号错误')) {
        fixedCode = fixedCode.replace(/(\w+)\]/g, '$1)');
        fixes.push({
          type: 'syntax',
          description: '修复方括号错误',
          line: error.line
        });
      }
      
      if (error.message.includes('重复的Business前缀')) {
        fixedCode = fixedCode.replace(/BusinessBusinessException/g, 'BusinessException');
        fixes.push({
          type: 'syntax',
          description: '修复重复的Business前缀',
          line: error.line
        });
      }
      
      if (error.message.includes('重复的等号')) {
        fixedCode = fixedCode.replace(/====/g, '===');
        fixes.push({
          type: 'syntax',
          description: '修复重复的等号',
          line: error.line
        });
      }
    });
    
    return { code: fixedCode, fixes };
  }
  
  async fixTypeErrors(code, validation) {
    let fixedCode = code;
    const fixes = [];
    // 类型错误修复逻辑
    return { code: fixedCode, fixes };
  }
  
  async fixImportErrors(code, validation) {
    let fixedCode = code;
    const fixes = [];
    // 导入错误修复逻辑
    return { code: fixedCode, fixes };
  }
  
  async fixBusinessLogicErrors(code, validation) {
    let fixedCode = code;
    const fixes = [];
    // 业务逻辑错误修复逻辑
    return { code: fixedCode, fixes };
  }
  
  // 指标计算方法
  calculateComplexity(code, context) {
    const lines = code.split('\n');
    const methods = (code.match(/function\s+\w+/g) || []).length;
    const conditions = (code.match(/if\s*\(|else\s*if\s*\(|switch\s*\(/g) || []).length;
    const loops = (code.match(/for\s*\(|while\s*\(|foreach\s*\(/g) || []).length;
    
    return {
      lines: lines.length,
      methods,
      conditions,
      loops,
      cyclomatic: methods + conditions + loops + 1
    };
  }
  
  calculateMaintainability(code, context) {
    const complexity = this.calculateComplexity(code, context);
    const maintainabilityIndex = Math.max(0, 171 - 5.2 * Math.log(complexity.lines) - 0.23 * complexity.cyclomatic);
    
    return {
      index: maintainabilityIndex,
      rating: maintainabilityIndex > 80 ? 'A' : maintainabilityIndex > 60 ? 'B' : maintainabilityIndex > 40 ? 'C' : 'D'
    };
  }
  
  calculateTestability(code, context) {
    const methods = (code.match(/function\s+\w+/g) || []).length;
    const dependencies = (code.match(/this\.\w+Service/g) || []).length;
    
    return {
      methods,
      dependencies,
      testabilityScore: Math.max(0, 100 - dependencies * 10)
    };
  }
  
  calculatePerformance(code, context) {
    const loops = (code.match(/for\s*\(|while\s*\(|foreach\s*\(/g) || []).length;
    const asyncCalls = (code.match(/await\s+/g) || []).length;
    
    return {
      loops,
      asyncCalls,
      performanceScore: Math.max(0, 100 - loops * 5 - asyncCalls * 2)
    };
  }
  
  // 辅助方法
  extractUsedClasses(code) {
    const classes = [];
    const matches = code.match(/([A-Z][a-zA-Z0-9_]*)/g);
    if (matches) {
      classes.push(...matches);
    }
    return [...new Set(classes)];
  }
  
  extractImportedClasses(code) {
    const imports = [];
    const matches = code.match(/import\s*\{\s*([^}]+)\s*\}\s*from/g);
    if (matches) {
      matches.forEach(match => {
        const importMatch = match.match(/import\s*\{\s*([^}]+)\s*\}\s*from/);
        if (importMatch) {
          const classNames = importMatch[1].split(',').map(name => name.trim());
          imports.push(...classNames);
        }
      });
    }
    return imports;
  }
  
  generateRecommendations(results) {
    const recommendations = [];
    
    if (results.errors.length > 0) {
      recommendations.push({
        type: 'error',
        message: '修复所有语法错误以提高代码质量',
        priority: 'high'
      });
    }
    
    if (results.warnings.length > 10) {
      recommendations.push({
        type: 'warning',
        message: '减少警告数量以提高代码质量',
        priority: 'medium'
      });
    }
    
    if (results.metrics.complexity?.cyclomatic > 10) {
      recommendations.push({
        type: 'complexity',
        message: '降低代码复杂度以提高可维护性',
        priority: 'medium'
      });
    }
    
    return recommendations;
  }
}

module.exports = QualityAssurance;
