/**
 * 简化的 API 生成脚本
 *
 * 这个脚本现在主要负责：
 * 1. 使用 @hey-api/openapi-ts 命令生成客户端代码
 * 2. 环境配置通过 openapi-ts.config.ts 处理
 */

const fs = require('fs');
const path = require('path');

// 从环境配置文件中读取 API_BASE_URL
function getApiBaseUrl() {
  try {
    // 首先尝试从 env/.env.dev 文件读取
    const envDevPath = path.join(process.cwd(), 'env', '.env.dev');
    if (fs.existsSync(envDevPath)) {
      const envContent = fs.readFileSync(envDevPath, 'utf8');
      const apiBaseUrlMatch = envContent.match(/API_BASE_URL=([^\r\n]+)/);

      if (apiBaseUrlMatch && apiBaseUrlMatch[1]) {
        return apiBaseUrlMatch[1].trim();
      }
    }

    // 如果上面的文件不存在，尝试从 TypeScript 环境配置文件读取
    const envConfigPath = path.join(process.cwd(), 'src', 'env', 'index.ts');
    if (fs.existsSync(envConfigPath)) {
      const envContent = fs.readFileSync(envConfigPath, 'utf8');
      const devConfigMatch = envContent.match(/dev:\s*\{[\s\S]*?BACKEND_BASE_URL:\s*['"`]([^'"`]+)['"`]/);

      if (devConfigMatch && devConfigMatch[1]) {
        return devConfigMatch[1].trim();
      }
    }

    throw new Error('无法找到 API_BASE_URL 或 BACKEND_BASE_URL 配置');
  } catch (error) {
    console.log(`读取环境配置失败: ${error.message}`);
    return 'http://localhost:8080'; // 默认值
  }
}

// 获取 API 基础 URL
const API_BASE_URL = getApiBaseUrl();

// 设置环境变量供后续使用
process.env.API_BASE_URL = API_BASE_URL;

// ANSI 颜色代码
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
  white: '\x1b[37m'
};

// 日志函数
function log(message, color = 'white') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function logSuccess(message) {
  log(`✓ ${message}`, 'green');
}

function logError(message) {
  log(`✗ ${message}`, 'red');
}

function logWarning(message) {
  log(`⚠ ${message}`, 'yellow');
}

function logInfo(message) {
  log(`ℹ ${message}`, 'blue');
}

// 显示环境配置信息
logInfo(`当前环境: ${process.env.NODE_ENV || 'development'}`);
logInfo(`API 服务器: ${API_BASE_URL}`);
logInfo(`已从 env/.env.dev 读取 API_BASE_URL 配置`);

/**
 * 检查自定义文件是否存在
 * 如果某些文件已经被自定义，我们不希望覆盖它们
 */
function checkCustomFiles() {
  const customFiles = [
    'client.gen.ts'  // 客户端文件通常是自定义的
  ];

  const outputDir = path.join(process.cwd(), 'src', 'lib', 'api');
  const existingCustomFiles = [];

  for (const file of customFiles) {
    const filePath = path.join(outputDir, file);
    if (fs.existsSync(filePath)) {
      // 检查文件是否包含自定义内容的标识
      const content = fs.readFileSync(filePath, 'utf8');

      // 检查是否有自定义配置的标识
      const customIndicators = [
        'getBaseUrl',
        'createDynamicClient',
        'getCurrentClientConfig',
        // 可以添加更多自定义标识
      ];

      const hasCustomContent = customIndicators.some(indicator =>
        content.includes(indicator)
      );

      if (hasCustomContent) {
        existingCustomFiles.push(file);
        logWarning(`检测到自定义文件: ${file}`);
      }
    }
  }

  return existingCustomFiles;
}

/**
 * 备份自定义文件
 */
function backupCustomFiles(customFiles) {
  if (customFiles.length === 0) return;

  logInfo('备份自定义文件...');
  const outputDir = path.join(process.cwd(), 'src', 'lib', 'api');
  const backupDir = path.join(process.cwd(), 'src', 'lib', 'api', 'backup');

  // 创建备份目录
  if (!fs.existsSync(backupDir)) {
    fs.mkdirSync(backupDir, { recursive: true });
  }

  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const timestampedBackupDir = path.join(backupDir, `backup-${timestamp}`);
  fs.mkdirSync(timestampedBackupDir);

  for (const file of customFiles) {
    const srcPath = path.join(outputDir, file);
    const destPath = path.join(timestampedBackupDir, file);
    fs.copyFileSync(srcPath, destPath);
    logInfo(`  备份: ${file} -> backup/${timestamp}/${file}`);
  }

  logSuccess(`自定义文件已备份到: backup/${timestamp}/`);
}

/**
 * 恢复自定义文件
 */
function restoreCustomFiles(customFiles) {
  if (customFiles.length === 0) return;

  logInfo('恢复自定义文件...');
  const outputDir = path.join(process.cwd(), 'src', 'lib', 'api');
  const backupDir = path.join(process.cwd(), 'src', 'lib', 'api', 'backup');

  // 找到最新的备份目录
  const backupDirs = fs.existsSync(backupDir)
    ? fs.readdirSync(backupDir)
        .filter(name => name.startsWith('backup-'))
        .sort()
        .reverse()
    : [];

  if (backupDirs.length === 0) {
    logWarning('没有找到备份文件，跳过恢复');
    return;
  }

  const latestBackupDir = path.join(backupDir, backupDirs[0]);

  for (const file of customFiles) {
    const srcPath = path.join(latestBackupDir, file);
    const destPath = path.join(outputDir, file);

    if (fs.existsSync(srcPath)) {
      fs.copyFileSync(srcPath, destPath);
      logInfo(`  恢复: ${file}`);
    }
  }

  logSuccess('自定义文件已恢复');
}

/**
 * 下载并保存 openapi.json 文件到本地
 */
function downloadOpenApiJson() {
  return new Promise((resolve, reject) => {
    const https = require('https');
    const fs = require('fs');
    const path = require('path');

    const fileUrl = `${API_BASE_URL}/openapi.json`;
    const outputPath = path.join(process.cwd(), 'scripts', 'openapi.json');

    logInfo(`下载 OpenAPI 规范文件: ${fileUrl}`);

    const startTime = Date.now();

    // 创建 HTTPS 代理（如果需要，可以忽略 SSL 证书验证）
    const agent = new https.Agent({
      rejectUnauthorized: false // 跳过 SSL 证书验证
    });

    https.get(fileUrl, { agent }, (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
        return;
      }

      let data = '';

      response.on('data', (chunk) => {
        data += chunk;
      });

      response.on('end', () => {
        try {
          // 验证 JSON 格式
          JSON.parse(data);

          // 写入文件
          fs.writeFileSync(outputPath, data, 'utf8');
          const executionTime = Date.now() - startTime;
          logSuccess(`OpenAPI 规范已保存到: scripts/openapi.json (${executionTime}ms)`);
          resolve();
        } catch (error) {
          reject(new Error(`JSON 格式错误: ${error.message}`));
        }
      });
    }).on('error', (error) => {
      reject(error);
    });
  });
}

/**
 * 使用 openapi-ts 命令生成客户端代码
 */
function generateWithOpenApiTS() {
  return new Promise((resolve, reject) => {
    logInfo('使用 @hey-api/openapi-ts 生成客户端代码...');

    const { exec } = require('child_process');
    const command = 'npx @hey-api/openapi-ts';

    logInfo(`执行命令: ${command}`);

    const startTime = Date.now();

    exec(command, { cwd: process.cwd() }, (error, stdout, stderr) => {
      const executionTime = Date.now() - startTime;

      if (error) {
        logError(`openapi-ts 执行失败 (${executionTime}ms)`);
        logError(`错误信息: ${error.message}`);
        if (stderr) {
          logError(`stderr: ${stderr}`);
        }
        reject(error);
        return;
      }

      if (stderr) {
        logWarning(`stderr: ${stderr}`);
      }

      logSuccess(`openapi-ts 执行成功 (${executionTime}ms)`);
      if (stdout) {
        logInfo(`输出: ${stdout}`);
      }

      resolve();
    });
  });
}

/**
 * 验证生成的文件
 */
function validateGeneratedFiles() {
  try {
    logInfo('验证生成的文件...');
    const outputDir = path.join(process.cwd(), 'src', 'lib', 'api');

    if (!fs.existsSync(outputDir)) {
      throw new Error('输出目录不存在');
    }

    const files = fs.readdirSync(outputDir);
    logInfo(`输出目录包含 ${files.length} 个文件:`);

    const requiredFiles = ['types.gen.ts', 'sdk.gen.ts', 'index.ts'];
    const generatedFiles = [];

    for (const file of files) {
      const filePath = path.join(outputDir, file);
      const stats = fs.statSync(filePath);

      // 只显示文件，不显示目录
      if (stats.isFile()) {
        const size = (stats.size / 1024).toFixed(2);
        logInfo(`  📄 ${file} (${size} KB)`);
        generatedFiles.push(file);
      }
    }

    // 检查必要文件
    const missingFiles = requiredFiles.filter(file => !generatedFiles.includes(file));
    if (missingFiles.length > 0) {
      logWarning(`缺少期望的文件: ${missingFiles.join(', ')}`);
    } else {
      logSuccess('所有期望的文件都已生成');
    }

    return true;
  } catch (error) {
    logError(`验证生成的文件失败: ${error.message}`);
    return false;
  }
}

/**
 * 主函数
 */
async function main() {
  const startTime = Date.now();

  log('='.repeat(60), 'cyan');
  log('API 客户端代码生成脚本', 'cyan');
  log('基于 @hey-api/openapi-ts', 'cyan');
  log('='.repeat(60), 'cyan');

  try {
    // 检查是否有自定义文件
    const customFiles = checkCustomFiles();

    if (customFiles.length > 0) {
      logInfo('检测到自定义文件，将在生成前进行备份');
      backupCustomFiles(customFiles);
    }

    // 下载 openapi.json 文件到本地
    await downloadOpenApiJson();

    // 使用 openapi-ts 生成代码
    await generateWithOpenApiTS();

    // 恢复自定义文件
    if (customFiles.length > 0) {
      restoreCustomFiles(customFiles);
    }

    // 验证生成的文件
    if (!validateGeneratedFiles()) {
      logWarning('文件验证发现问题，但生成过程已完成');
    }

    const totalTime = Date.now() - startTime;
    logSuccess(`API 客户端代码生成完成！总耗时: ${totalTime}ms`);
    logSuccess('生成的文件位于 src/lib/api/ 目录');

    if (customFiles.length > 0) {
      logInfo('自定义文件已保持不变，避免覆盖手动配置');
    }

  } catch (error) {
    const totalTime = Date.now() - startTime;
    logError(`脚本执行失败 (${totalTime}ms): ${error.message}`);
    process.exit(1);
  }
}

// 执行主函数
if (require.main === module) {
  main();
}