/**
 * 多阶段转换管道
 * 为AI自动生成打下基石
 */

const ConversionRulesDatabase = require('./conversion-rules-database');

class ConversionPipeline {
  constructor() {
    this.rulesDB = new ConversionRulesDatabase();
    this.stages = [
      'preprocessing',    // 预处理
      'syntax',          // 语法转换
      'semantic',        // 语义转换
      'context',         // 上下文转换
      'validation',      // 验证
      'postprocessing'   // 后处理
    ];
    
    this.stageHandlers = {
      preprocessing: this.preprocess.bind(this),
      syntax: this.convertSyntax.bind(this),
      semantic: this.convertSemantic.bind(this),
      context: this.convertContext.bind(this),
      validation: this.validate.bind(this),
      postprocessing: this.postprocess.bind(this)
    };
  }
  
  /**
   * 执行完整转换管道
   */
  async convert(phpCode, context = {}) {
    let convertedCode = phpCode;
    const results = {
      original: phpCode,
      stages: {},
      errors: [],
      warnings: [],
      metrics: {}
    };
    
    console.log('🚀 开始多阶段转换管道...');
    
    for (const stage of this.stages) {
      try {
        console.log(`📋 执行阶段: ${stage}`);
        const startTime = Date.now();
        
        convertedCode = await this.stageHandlers[stage](convertedCode, context, results);
        
        const endTime = Date.now();
        results.stages[stage] = {
          input: results.stages[stage - 1]?.output || phpCode,
          output: convertedCode,
          duration: endTime - startTime,
          success: true
        };
        
        console.log(`✅ 阶段 ${stage} 完成 (${endTime - startTime}ms)`);
      } catch (error) {
        console.error(`❌ 阶段 ${stage} 失败:`, error.message);
        results.errors.push({
          stage,
          error: error.message,
          stack: error.stack
        });
        results.stages[stage] = {
          success: false,
          error: error.message
        };
      }
    }
    
    results.final = convertedCode;
    results.metrics = this.calculateMetrics(results);
    
    console.log('🎉 转换管道完成!');
    return results;
  }
  
  /**
   * 预处理阶段
   */
  async preprocess(code, context, results) {
    console.log('  🔧 预处理: 清理和标准化代码...');
    
    // 清理代码
    let processed = code
      // 移除多余的空白
      .replace(/\s+/g, ' ')
      .replace(/\n\s*\n/g, '\n')
      // 标准化换行
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      // 移除注释中的特殊字符
      .replace(/\/\*[\s\S]*?\*\//g, (match) => {
        return match.replace(/[^\x20-\x7E\n]/g, '');
      });
    
    // 检测代码特征
    const features = this.detectFeatures(processed);
    context.features = features;
    
    console.log(`  📊 检测到特征: ${Object.keys(features).join(', ')}`);
    
    return processed;
  }
  
  /**
   * 语法转换阶段
   */
  async convertSyntax(code, context, results) {
    console.log('  🔄 语法转换: 基础PHP到TypeScript转换...');
    
    // 应用基础语法转换规则
    let converted = this.rulesDB.applyRules(code, 'syntax');
    
    // 应用类型转换规则
    converted = this.rulesDB.applyRules(converted, 'types');
    
    // 应用方法转换规则
    converted = this.rulesDB.applyRules(converted, 'methods');
    
    // 应用数组和对象转换规则
    converted = this.rulesDB.applyRules(converted, 'collections');
    
    // 应用异常处理转换规则
    converted = this.rulesDB.applyRules(converted, 'exceptions');
    
    // 应用字符串处理规则
    converted = this.rulesDB.applyRules(converted, 'strings');
    
    console.log(`  📈 语法转换完成，代码长度: ${converted.length}`);
    
    return converted;
  }
  
  /**
   * 语义转换阶段
   */
  async convertSemantic(code, context, results) {
    console.log('  🧠 语义转换: 业务逻辑语义转换...');
    
    // 应用服务调用转换规则
    let converted = this.rulesDB.applyRules(code, 'services');
    
    // 智能识别和转换业务逻辑模式
    converted = this.convertBusinessPatterns(converted, context);
    
    // 转换控制流
    converted = this.convertControlFlow(converted, context);
    
    console.log(`  🎯 语义转换完成，业务模式识别: ${context.features?.businessPatterns?.length || 0}个`);
    
    return converted;
  }
  
  /**
   * 上下文转换阶段
   */
  async convertContext(code, context, results) {
    console.log('  🎭 上下文转换: 根据代码上下文优化转换...');
    
    let converted = code;
    
    // 根据文件类型应用不同的转换策略
    if (context.fileType === 'service') {
      converted = this.convertServiceContext(converted, context);
    } else if (context.fileType === 'controller') {
      converted = this.convertControllerContext(converted, context);
    } else if (context.fileType === 'entity') {
      converted = this.convertEntityContext(converted, context);
    }
    
    // 根据业务领域应用特定转换
    if (context.businessDomain) {
      converted = this.convertBusinessDomain(converted, context);
    }
    
    console.log(`  🏗️ 上下文转换完成，文件类型: ${context.fileType || 'unknown'}`);
    
    return converted;
  }
  
  /**
   * 验证阶段
   */
  async validate(code, context, results) {
    console.log('  ✅ 验证: 检查转换质量和语法正确性...');
    
    const validation = {
      syntax: this.validateSyntax(code),
      types: this.validateTypes(code),
      imports: this.validateImports(code),
      business: this.validateBusinessLogic(code, context)
    };
    
    // 收集验证结果
    const errors = [];
    const warnings = [];
    
    Object.entries(validation).forEach(([type, result]) => {
      if (result.errors) {
        errors.push(...result.errors.map(e => ({ type, ...e })));
      }
      if (result.warnings) {
        warnings.push(...result.warnings.map(w => ({ type, ...w })));
      }
    });
    
    results.errors.push(...errors);
    results.warnings.push(...warnings);
    
    console.log(`  📊 验证完成: ${errors.length}个错误, ${warnings.length}个警告`);
    
    return code;
  }
  
  /**
   * 后处理阶段
   */
  async postprocess(code, context, results) {
    console.log('  🎨 后处理: 最终优化和格式化...');
    
    // 应用语法错误修复规则
    let processed = this.rulesDB.applyRules(code, 'syntaxFixes');
    
    // 格式化代码
    processed = this.formatCode(processed);
    
    // 添加必要的导入语句
    processed = this.addImports(processed, context);
    
    console.log(`  🎉 后处理完成，最终代码长度: ${processed.length}`);
    
    return processed;
  }
  
  /**
   * 检测代码特征
   */
  detectFeatures(code) {
    const features = {
      hasClasses: /class\s+\w+/.test(code),
      hasFunctions: /function\s+\w+/.test(code),
      hasArrays: /array\s*\(/.test(code),
      hasObjects: /->\s*\w+/.test(code),
      hasExceptions: /throw\s+new/.test(code),
      hasServices: /new\s+[A-Z]\w+Service/.test(code),
      hasControllers: /class\s+\w+Controller/.test(code),
      hasEntities: /@Entity|@Table/.test(code),
      businessPatterns: []
    };
    
    // 检测业务模式
    const businessPatterns = [
      { pattern: /success\s*\(/, name: 'success_response' },
      { pattern: /error\s*\(/, name: 'error_response' },
      { pattern: /validate\s*\(/, name: 'validation' },
      { pattern: /cache\s*\(/, name: 'caching' },
      { pattern: /log\s*\(/, name: 'logging' }
    ];
    
    businessPatterns.forEach(({ pattern, name }) => {
      if (pattern.test(code)) {
        features.businessPatterns.push(name);
      }
    });
    
    return features;
  }
  
  /**
   * 转换业务模式
   */
  convertBusinessPatterns(code, context) {
    let converted = code;
    
    // 转换success响应
    converted = converted.replace(/return\s+success\s*\(([^)]+)\)/g, (match, data) => {
      return `return { success: true, data: ${data} };`;
    });
    
    // 转换error响应
    converted = converted.replace(/return\s+error\s*\(([^)]+)\)/g, (match, message) => {
      return `throw new BusinessException(${message});`;
    });
    
    return converted;
  }
  
  /**
   * 转换控制流
   */
  convertControlFlow(code, context) {
    let converted = code;
    
    // 转换PHP控制流到TypeScript
    converted = converted.replace(/foreach\s*\(\s*([^)]+)\s+as\s+([^)]+)\s*\)/g, 'for (const $2 of $1)');
    converted = converted.replace(/foreach\s*\(\s*([^)]+)\s+as\s+([^)]+)\s*=>\s*([^)]+)\s*\)/g, 'for (const [$3, $2] of Object.entries($1))');
    
    return converted;
  }
  
  /**
   * 服务上下文转换
   */
  convertServiceContext(code, context) {
    // 服务特定的转换逻辑
    return code;
  }
  
  /**
   * 控制器上下文转换
   */
  convertControllerContext(code, context) {
    // 控制器特定的转换逻辑
    return code;
  }
  
  /**
   * 实体上下文转换
   */
  convertEntityContext(code, context) {
    // 实体特定的转换逻辑
    return code;
  }
  
  /**
   * 业务领域转换
   */
  convertBusinessDomain(code, context) {
    // 根据业务领域应用特定转换
    return code;
  }
  
  /**
   * 验证语法
   */
  validateSyntax(code) {
    const errors = [];
    const warnings = [];
    
    // 检查基本语法错误
    if (code.includes(']]')) {
      errors.push({ message: '发现方括号错误', line: this.findLineNumber(code, ']]') });
    }
    
    if (code.includes('BusinessBusinessException')) {
      errors.push({ message: '发现重复的Business前缀', line: this.findLineNumber(code, 'BusinessBusinessException') });
    }
    
    return { errors, warnings };
  }
  
  /**
   * 验证类型
   */
  validateTypes(code) {
    const errors = [];
    const warnings = [];
    
    // 类型验证逻辑
    return { errors, warnings };
  }
  
  /**
   * 验证导入
   */
  validateImports(code) {
    const errors = [];
    const warnings = [];
    
    // 导入验证逻辑
    return { errors, warnings };
  }
  
  /**
   * 验证业务逻辑
   */
  validateBusinessLogic(code, context) {
    const errors = [];
    const warnings = [];
    
    // 业务逻辑验证
    return { errors, warnings };
  }
  
  /**
   * 格式化代码
   */
  formatCode(code) {
    // 简单的代码格式化
    return code
      .replace(/\s+/g, ' ')
      .replace(/\n\s*\n/g, '\n')
      .trim();
  }
  
  /**
   * 添加导入语句
   */
  addImports(code, context) {
    // 根据代码内容添加必要的导入
    let imports = [];
    
    if (code.includes('BusinessException')) {
      imports.push("import { BusinessException } from '@wwjCommon/exceptions/business.exception';");
    }
    
    if (code.includes('@Injectable')) {
      imports.push("import { Injectable } from '@nestjs/common';");
    }
    
    if (imports.length > 0) {
      return imports.join('\n') + '\n\n' + code;
    }
    
    return code;
  }
  
  /**
   * 计算指标
   */
  calculateMetrics(results) {
    const originalLength = results.original.length;
    const finalLength = results.final.length;
    
    return {
      originalLength,
      finalLength,
      compressionRatio: (originalLength - finalLength) / originalLength,
      errorCount: results.errors.length,
      warningCount: results.warnings.length,
      stageCount: Object.keys(results.stages).length,
      totalDuration: Object.values(results.stages).reduce((sum, stage) => sum + (stage.duration || 0), 0)
    };
  }
  
  /**
   * 查找行号
   */
  findLineNumber(code, searchText) {
    const lines = code.split('\n');
    for (let i = 0; i < lines.length; i++) {
      if (lines[i].includes(searchText)) {
        return i + 1;
      }
    }
    return -1;
  }
}

module.exports = ConversionPipeline;
