#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const BusinessLogicConverter = require('./business-logic-converter');

/**
 * ⚙️ 服务生成器
 * 专门负责生成和更新NestJS服务
 */
class ServiceGenerator {
  constructor() {
    this.config = {
      phpBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-php/niucloud',
      nestjsBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest/src/core',
      discoveryResultPath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/tools/php-discovery-result.json'
    };
    
    this.discoveryData = null;
    this.converter = new BusinessLogicConverter();
    this.stats = {
      servicesCreated: 0,
      servicesUpdated: 0,
      methodsProcessed: 0,
      errors: 0
    };
  }

  /**
   * 运行服务生成
   */
  async run() {
    console.log('⚙️ 启动服务生成器...');
    
    try {
      // 加载发现数据
      await this.loadDiscoveryData();
      
      // 生成服务
      await this.generateServices();
      
      // 更新服务为真实业务逻辑
      await this.updateAllServicesWithRealLogic();
      
      // 生成统计报告
      this.generateStatsReport();
      
    } catch (error) {
      console.error('❌ 服务生成过程中发生错误:', error.message);
      this.stats.errors++;
      throw error;
    }
  }

  /**
   * 加载PHP文件发现结果
   */
  async loadDiscoveryData() {
    try {
      const data = fs.readFileSync(this.config.discoveryResultPath, 'utf-8');
      this.discoveryData = JSON.parse(data);
      console.log('   ✅ 成功加载PHP文件发现结果');
    } catch (error) {
      console.error('   ❌ 加载发现数据失败:', error.message);
      throw error;
    }
  }

  /**
   * 生成服务
   */
  async generateServices() {
    console.log('   🔨 生成服务文件...');
    
    // 检查是否有服务数据
    if (!this.discoveryData.services || Object.keys(this.discoveryData.services).length === 0) {
      console.log('   ⚠️  未发现PHP服务，跳过生成');
      return;
    }
    
    let processedCount = 0;
    
    // 服务数据结构是按层级分组的，需要遍历所有层级
    for (const [layerName, services] of Object.entries(this.discoveryData.services)) {
      console.log(`   📁 处理服务层级: ${layerName}, 服务数量: ${Object.keys(services).length}`);
      
      for (const [serviceName, serviceInfo] of Object.entries(services)) {
        console.log(`   ⚙️ 处理服务: ${serviceName}`);
        
        try {
          const correctModuleName = this.extractModuleNameFromServicePath(serviceInfo.filePath);
          const layer = this.extractLayerFromServicePath(serviceInfo.filePath);
          
          // 检查PHP项目是否有对应的服务目录
          if (!this.hasPHPServices(correctModuleName, layer)) {
            console.log(`   ⚠️  模块 ${correctModuleName} 在PHP项目中无${layer}服务，跳过`);
            continue;
          }
          
          await this.createService(correctModuleName, serviceName, serviceInfo, layer);
          processedCount++;
          console.log(`   ✅ 成功创建服务: ${correctModuleName}/${serviceName}`);
        } catch (error) {
          console.error(`   ❌ 创建服务失败 ${serviceName}:`, error.message);
          this.stats.errors++;
        }
      }
    }
    
    this.stats.servicesCreated = processedCount;
    console.log(`   ✅ 创建了 ${this.stats.servicesCreated} 个服务`);
  }

  /**
   * 更新所有服务为真实业务逻辑
   */
  async updateAllServicesWithRealLogic() {
    console.log('   🔨 更新服务为真实业务逻辑...');
    
    let processedCount = 0;
    
    // 服务数据结构是按层级分组的，需要遍历所有层级
    for (const [layerName, services] of Object.entries(this.discoveryData.services)) {
      console.log(`   📁 处理服务层级: ${layerName}, 服务数量: ${Object.keys(services).length}`);
      for (const [serviceName, serviceInfo] of Object.entries(services)) {
        console.log(`   ⚙️ 处理服务: ${serviceName}`);
        
        try {
          const correctModuleName = this.extractModuleNameFromServicePath(serviceInfo.filePath);
          const layer = this.extractLayerFromServicePath(serviceInfo.filePath);
          await this.updateServiceWithRealLogic(correctModuleName, serviceName, serviceInfo, layer);
          processedCount++;
          console.log(`   ✅ 成功更新服务: ${correctModuleName}/${serviceName}`);
        } catch (error) {
          console.error(`   ❌ 更新服务失败 ${serviceName}:`, error.message);
          this.stats.errors++;
        }
      }
    }
    
    this.stats.servicesUpdated = processedCount;
    console.log(`   ✅ 更新了 ${this.stats.servicesUpdated} 个服务`);
  }

  /**
   * 创建服务
   */
  async createService(moduleName, serviceName, serviceInfo, layer) {
    // 先去掉层级后缀，再去掉Service后缀
    const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
    const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
    const servicePath = path.join(
      this.config.nestjsBasePath, 
      moduleName, 
      'services', 
      layer, 
      `${this.toKebabCase(baseName)}.service.ts`
    );
    
    // 确保目录存在
    const serviceDir = path.dirname(servicePath);
    if (!fs.existsSync(serviceDir)) {
      fs.mkdirSync(serviceDir, { recursive: true });
    }
    
    // 检查是否有对应的PHP服务文件
    // 从服务名中提取基础类名（去掉_layer后缀）
    const baseServiceName = serviceName.replace(/_(admin|api|core)$/, '');
    const phpServicePath = path.join(this.config.phpBasePath, 'app/service', layer, moduleName, `${baseServiceName}.php`);
    if (!fs.existsSync(phpServicePath)) {
      console.log(`     ❌ 未找到PHP服务文件，跳过生成: ${phpServicePath}`);
      return;
    }
    
    // 生成基础服务内容
    const serviceContent = this.generateBasicServiceContent(moduleName, serviceName, layer);
    
    // 写入文件
    fs.writeFileSync(servicePath, serviceContent);
    console.log(`     ✅ 创建服务: ${moduleName}/${layer}/${this.toKebabCase(baseName)}.service.ts`);
    
    this.stats.servicesCreated++;
  }

  /**
   * 更新服务为真实逻辑
   */
  async updateServiceWithRealLogic(moduleName, serviceName, serviceInfo, layer) {
    // 先去掉层级后缀，再去掉Service后缀
    const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
    const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
    const servicePath = path.join(
      this.config.nestjsBasePath, 
      moduleName, 
      'services', 
      layer, 
      `${this.toKebabCase(baseName)}.service.ts`
    );
    
    if (!fs.existsSync(servicePath)) {
      console.log(`     ⚠️ 服务文件不存在: ${servicePath}`);
      return;
    }
    
    try {
      // 读取PHP服务文件
      const phpServicePath = serviceInfo.filePath;
      const phpContent = fs.readFileSync(phpServicePath, 'utf-8');
      
      // 提取PHP方法
      const phpMethods = this.converter.extractPHPMethods(phpContent);
      
      if (phpMethods.length === 0) {
        console.log(`     ⚠️ 未找到PHP方法: ${serviceName}`);
        return;
      }
      
      console.log(`     📝 找到 ${phpMethods.length} 个PHP方法`);
      
      // 生成NestJS服务内容
      const nestjsContent = this.generateRealServiceContent(moduleName, serviceName, layer, phpMethods);
      
      // 写入文件
      fs.writeFileSync(servicePath, nestjsContent);
      console.log(`     ✅ 更新服务: ${moduleName}/${layer}/${this.toKebabCase(baseName)}.service.ts`);
      
      this.stats.methodsProcessed += phpMethods.length;
      
    } catch (error) {
      console.log(`     ❌ 无法更新服务 ${serviceName}: ${error.message}`);
      this.stats.errors++;
    }
  }

  /**
   * 生成基础服务内容
   */
  generateBasicServiceContent(moduleName, serviceName, layer) {
    // 先去掉层级后缀，再去掉Service后缀
    const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
    const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
    
    // 正确的命名规范：服务类名（与PHP/Java保持一致）
    let className = `${baseName}Service`;
    if (layer === 'core') {
      // Core层服务需要Core前缀
      className = baseName.startsWith('Core') ? `${baseName}Service` : `Core${baseName}Service`;
    } else {
      // admin和api层直接使用业务名称
      className = `${baseName}Service`;
    }

    // 获取基础设施导入
    const infrastructureImports = this.getInfrastructureImports();

    return `import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { BaseService } from '@wwjCommon/base/base.service';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';

/**
 * ${className} - ${layer}层服务
 * 继承BaseService，使用TypeORM Repository模式
 * 对应 Java: @Service + @Autowired
 * 对应 PHP: extends BaseCoreService
 * 
 * 使用Common层基础设施：
 * - CacheService (缓存，对应PHP Cache::)
 * - ConfigService (配置读取，对应PHP Config::get)
 * - LoggingService (日志记录，对应PHP Log::write)
 * 
 * 使用Vendor层业务服务：
 * - UploadService (文件上传，对应PHP Storage/UploadLoader)
 * - PayService (支付服务，对应PHP PayLoader)
 * - SmsService (短信服务，对应PHP SmsLoader)
 * - NoticeService (通知服务，对应PHP NoticeService)
 */
@Injectable()
export class ${className} extends BaseService<any> {
  private readonly logger = new Logger(${className}.name);

  constructor(
    @InjectRepository(Object)
    protected readonly repository: Repository<any>,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly loggingService: LoggingService,
    private readonly uploadService: UploadService,
    private readonly payService: PayService,
    private readonly smsService: SmsService,
    private readonly noticeService: NoticeService,
  ) {
    super(repository);
  }

  // 服务方法需要基于真实PHP服务类解析
  // 禁止假设方法，所有方法必须来自PHP源码
  // 可使用注入的服务：configService, loggingService, uploadService, payService, smsService, noticeService
}
`;
  }

  /**
   * 获取基础设施导入
   */
  getInfrastructureImports() {
    return `import { ConfigService } from '@nestjs/config';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';`;
  }

  /**
   * 生成真实服务内容
   */
  generateRealServiceContent(moduleName, serviceName, layer, phpMethods) {
    // 先去掉层级后缀，再去掉Service后缀
    const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
    const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
    
    // 正确的命名规范：服务类名（与PHP/Java保持一致）
    let className = `${baseName}Service`;
    if (layer === 'core') {
      // Core层服务需要Core前缀
      className = baseName.startsWith('Core') ? `${baseName}Service` : `Core${baseName}Service`;
    } else {
      // admin和api层直接使用业务名称
      className = `${baseName}Service`;
    }
    
    // BaseService 中已存在的方法，需要避免覆盖
    const baseServiceMethods = ['create', 'update', 'delete', 'find', 'findOne', 'findAll', 'save', 'remove'];
    
    const methodImplementations = phpMethods.filter(method => method && method.name).map(method => {
      // 调试：检查参数格式
      console.log(`🔍 调试参数: ${method.name}`, method.parameters);
      const parameters = this.converter.generateServiceParameters(method.parameters);
      
      // 检查是否与BaseService方法冲突
      if (baseServiceMethods.includes(method.name)) {
        // 如果方法名与BaseService冲突，重命名方法
        const newMethodName = `${method.name}Record`;
        console.log(`⚠️ 方法名冲突，重命名: ${method.name} -> ${newMethodName}`);
        
        const realLogic = this.generateRealServiceLogic(method);
        const logic = method.logic || { type: 'real', description: '基于真实PHP业务逻辑' };
        
        return `  /**
   * ${newMethodName} (原方法名: ${method.name})
   * 对应 PHP: ${serviceName}::${method.name}()
   * 逻辑类型: ${logic.type} - ${logic.description}
   * 注意: 为避免与BaseService方法冲突，已重命名
   */
  async ${newMethodName}(${parameters}) {
${realLogic}
  }`;
      } else {
        // 正常生成方法
        const realLogic = this.generateRealServiceLogic(method);
        const logic = method.logic || { type: 'real', description: '基于真实PHP业务逻辑' };
        
        return `  /**
   * ${method.name}
   * 对应 PHP: ${serviceName}::${method.name}()
   * 逻辑类型: ${logic.type} - ${logic.description}
   */
  async ${method.name}(${parameters}) {
${realLogic}
  }`;
      }
    }).join('\n\n');

    return `import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { BaseService } from '@wwjCommon/base/base.service';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';

@Injectable()
export class ${className} extends BaseService<any> {
  private readonly logger = new Logger(${className}.name);

  constructor(
    @InjectRepository(Object)
    protected readonly repository: Repository<any>,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly loggingService: LoggingService,
    private readonly uploadService: UploadService,
    private readonly payService: PayService,
    private readonly smsService: SmsService,
    private readonly noticeService: NoticeService,
  ) {
    super(repository);
  }

${methodImplementations}
}
`;
  }

  /**
   * 生成真实服务逻辑
   */
  generateRealServiceLogic(method) {
    if (!method || !method.name) {
      return `    // 方法信息缺失
    return { success: false, message: "Method information missing" };`;
    }
    
    // 使用method.logic而不是method.body
    const phpLogic = method.logic || method.body || '';
    
    if (!phpLogic.trim()) {
      return `    // TODO: 实现${method.name}业务逻辑
    throw new Error('${method.name} not implemented');`;
    }
    
    // 转换PHP代码到TypeScript
    const tsBody = this.converter.convertBusinessLogic('', method.name, phpLogic);
    
    return `    // 基于PHP真实逻辑: ${method.name}
    // PHP原文: ${phpLogic.substring(0, 150).replace(/\n/g, ' ')}...
${tsBody}`;
  }

  /**
   * 从服务路径提取模块名
   */
  extractModuleNameFromServicePath(filePath) {
    // 从路径中提取模块名
    const pathParts = filePath.split('/');
    const serviceIndex = pathParts.findIndex(part => part === 'service');
    
    if (serviceIndex > 0 && serviceIndex < pathParts.length - 2) {
      // service目录后面应该是层级(admin/api/core)，再后面是模块名
      // 路径格式: .../app/service/admin/home/AuthSiteService.php
      // 索引:     .../8   9      10    11   12
      return pathParts[serviceIndex + 2];
    }
    
    // 如果找不到service目录，尝试从文件名推断
    const fileName = path.basename(filePath, '.php');
    if (fileName.includes('Service')) {
      return fileName.replace('Service', '').toLowerCase();
    }
    
    return 'unknown';
  }

  /**
   * 从服务路径提取层级
   */
  extractLayerFromServicePath(filePath) {
    // 从路径中提取层级信息
    if (filePath.includes('/admin/')) {
      return 'admin';
    } else if (filePath.includes('/api/')) {
      return 'api';
    } else if (filePath.includes('/core/')) {
      return 'core';
    }
    
    return 'core'; // 默认为core层
  }

  /**
   * 转换为驼峰命名
   */
  toCamelCase(str) {
    return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
      return index === 0 ? word.toLowerCase() : word.toUpperCase();
    }).replace(/\s+/g, '');
  }

  /**
   * 转换为PascalCase
   */
  toPascalCase(str) {
    return str.replace(/(^|-)([a-z])/g, (match, p1, p2) => p2.toUpperCase());
  }

  /**
   * 转换为kebab-case（我们框架的标准命名格式）
   */
  toKebabCase(str) {
    return str
      .replace(/([A-Z])/g, '-$1')
      .replace(/^-/, '')
      .toLowerCase();
  }

  /**
   * 检查模块是否有PHP服务
   */
  hasPHPServices(moduleName, layer) {
    const phpProjectPath = path.join(__dirname, '../../niucloud-php/niucloud');
    const servicePath = path.join(phpProjectPath, 'app/service', layer, moduleName);
    
    if (!fs.existsSync(servicePath)) return false;
    
    // 检查目录内是否有PHP文件
    try {
      const files = fs.readdirSync(servicePath);
      return files.some(file => file.endsWith('.php'));
    } catch (error) {
      return false;
    }
  }

  /**
   * 生成统计报告
   */
  generateStatsReport() {
    console.log('\n📊 服务生成统计报告');
    console.log('='.repeat(50));
    console.log(`✅ 创建服务数量: ${this.stats.servicesCreated}`);
    console.log(`🔄 更新服务数量: ${this.stats.servicesUpdated}`);
    console.log(`📝 处理方法数量: ${this.stats.methodsProcessed}`);
    console.log(`❌ 错误数量: ${this.stats.errors}`);
    console.log(`📈 成功率: ${this.stats.servicesCreated > 0 ? ((this.stats.servicesCreated - this.stats.errors) / this.stats.servicesCreated * 100).toFixed(2) : 0}%`);
  }
}

// 如果直接运行此文件
if (require.main === module) {
  const generator = new ServiceGenerator();
  generator.run().catch(console.error);
}

module.exports = ServiceGenerator;
