#!/usr/bin/env node

/**
 * API 文档自动生成脚本
 * 使用 OpenAPI 从后端 Swagger 自动生成前端文档
 */

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

// 配置
const config = {
  // 后端服务地址
  backendUrl: process.env.BACKEND_URL || 'http://localhost:3000',
  
  // 文档输出目录
  docsDir: path.join(__dirname, '../src/wwjcloud/openapi/api'),
  
  // API 分组配置
  apiGroups: {
    api: {
      name: '前台 API',
      swaggerPath: '/api/api-json',
      outputDir: 'frontend',
      description: '前台用户访问的 API 接口',
      prefix: '/api'
    },
    adminapi: {
      name: '后台 API', 
      swaggerPath: '/api/adminapi-json',
      outputDir: 'adminapi',
      description: '后台管理员访问的 API 接口',
      prefix: '/adminapi'
    }
  }
};

/**
 * 获取 Swagger JSON
 */
async function getSwaggerJson(group) {
  try {
    const url = `${config.backendUrl}${group.swaggerPath}`;
    console.log(`正在获取 ${group.name} API 文档: ${url}`);
    
    const response = await axios.get(url);
    return response.data;
  } catch (error) {
    console.error(`获取 ${group.name} API 文档失败:`, error.message);
    return null;
  }
}

/**
 * 生成 API 概览文档
 */
function generateOverview(group) {
  return `---
title: ${group.name}
description: ${group.description}
---

# ${group.name}

::: info ${group.name} 说明

${group.description}

:::

## API 基础信息

- **基础路径**: \`${group.prefix}/\`
- **认证方式**: JWT Bearer Token
- **内容类型**: \`application/json\`
- **字符编码**: \`UTF-8\`

## 模块列表

::: tip 自动生成

此文档由后端 Swagger 自动生成，包含最新的 API 接口信息。

:::

## 认证流程

### 获取 Token

\`\`\`http
POST ${group.prefix}/auth/login
Content-Type: application/json

{
  "username": "user@example.com",
  "password": "password123"
}
\`\`\`

## 响应格式

所有 API 都遵循统一的响应格式：

\`\`\`json
{
  "code": 200,
  "message": "success",
  "data": {
    // 具体数据
  }
}
\`\`\`

## 错误处理

API 错误响应格式：

\`\`\`json
{
  "code": 400,
  "message": "参数错误",
  "data": null
}
\`\`\`

## 状态码说明

| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |

## 开发工具

### Swagger UI

访问 \`${config.backendUrl}${group.prefix}\` 查看完整的 API 文档和在线测试功能。

### 在线测试

每个 API 分组都提供 Swagger UI 界面，支持：

- API 文档查看
- 在线测试
- 参数验证
- 响应示例
`;
}

/**
 * 生成模块 API 文档
 */
function generateModuleDoc(group, tag, paths) {
  const moduleName = tag.name.toLowerCase().replace(/\s+/g, '-');
  const moduleDesc = tag.description || `${moduleName} 相关接口`;
  
  let markdown = `---
title: ${moduleName} API
description: ${moduleDesc}
---

# ${moduleName} API

::: info ${moduleName} API

${moduleDesc}

:::

## 基础信息

- **模块路径**: \`${group.prefix}/${moduleName.toLowerCase()}/\`
- **认证方式**: JWT Bearer Token（部分接口需要）
- **内容类型**: \`application/json\`

## API 列表

`;

  // 查找该标签下的所有接口
  Object.keys(paths).forEach(path => {
    Object.keys(paths[path]).forEach(method => {
      const operation = paths[path][method];
      
      if (operation.tags && operation.tags.includes(tag.name)) {
        markdown += generateApiDoc(path, method, operation, group.prefix);
      }
    });
  });

  return markdown;
}

/**
 * 生成单个 API 文档
 */
function generateApiDoc(path, method, operation, prefix) {
  const summary = operation.summary || operation.operationId || '未命名接口';
  const description = operation.description || '';
  
  let doc = `### ${summary}\n\n`;
  
  // 接口地址
  doc += `**接口地址**: \`${method.toUpperCase()} ${path}\`\n\n`;
  
  // 接口描述
  if (description) {
    doc += `**接口描述**: ${description}\n\n`;
  }

  // 请求参数
  if (operation.parameters && operation.parameters.length > 0) {
    doc += `**请求参数**:\n\n`;
    
    if (method === 'get') {
      doc += `| 参数 | 类型 | 必填 | 说明 |\n`;
      doc += `|------|------|------|------|\n`;
      
      operation.parameters.forEach(param => {
        const required = param.required ? '是' : '否';
        const type = param.type || param.schema?.type || 'string';
        doc += `| ${param.name} | ${type} | ${required} | ${param.description || ''} |\n`;
      });
      doc += `\n`;
    } else {
      doc += `\`\`\`json\n`;
      doc += `{\n`;
      operation.parameters.forEach((param, index) => {
        const comma = index < operation.parameters.length - 1 ? ',' : '';
        const type = param.type || param.schema?.type || 'string';
        doc += `  "${param.name}": "${type}"${comma}\n`;
      });
      doc += `}\n`;
      doc += `\`\`\`\n\n`;
    }
  }

  // 请求体
  if (operation.requestBody) {
    doc += `**请求体**:\n\n`;
    doc += `\`\`\`json\n`;
    if (operation.requestBody.content && operation.requestBody.content['application/json']) {
      const schema = operation.requestBody.content['application/json'].schema;
      if (schema && schema.properties) {
        doc += `{\n`;
        Object.keys(schema.properties).forEach((prop, index) => {
          const comma = index < Object.keys(schema.properties).length - 1 ? ',' : '';
          const type = schema.properties[prop].type || 'string';
          doc += `  "${prop}": "${type}"${comma}\n`;
        });
        doc += `}\n`;
      } else {
        doc += `{\n`;
        doc += `  // 请求体内容\n`;
        doc += `}\n`;
      }
    } else {
      doc += `{\n`;
      doc += `  // 请求体内容\n`;
      doc += `}\n`;
    }
    doc += `\`\`\`\n\n`;
  }

  // 响应示例
  if (operation.responses) {
    doc += `**响应示例**:\n\n`;
    const successResponse = operation.responses['200'] || operation.responses['201'];
    if (successResponse) {
      doc += `\`\`\`json\n`;
      doc += `{\n`;
      doc += `  "code": 200,\n`;
      doc += `  "message": "success",\n`;
      doc += `  "data": {\n`;
      if (successResponse.content && successResponse.content['application/json']) {
        const schema = successResponse.content['application/json'].schema;
        if (schema && schema.properties) {
          Object.keys(schema.properties).forEach((prop, index) => {
            const comma = index < Object.keys(schema.properties).length - 1 ? ',' : '';
            const type = schema.properties[prop].type || 'string';
            doc += `    "${prop}": "${type}"${comma}\n`;
          });
        } else {
          doc += `    // 响应数据\n`;
        }
      } else {
        doc += `    // 响应数据\n`;
      }
      doc += `  }\n`;
      doc += `}\n`;
      doc += `\`\`\`\n\n`;
    }
  }

  doc += `---\n\n`;
  return doc;
}

/**
 * 保存文档到文件
 */
function saveDocument(outputPath, content) {
  try {
    // 确保目录存在
    const dir = path.dirname(outputPath);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    
    fs.writeFileSync(outputPath, content, 'utf8');
    console.log(`文档已保存: ${outputPath}`);
  } catch (error) {
    console.error(`保存文档失败: ${outputPath}`, error.message);
  }
}

/**
 * 更新侧边栏配置
 */
function updateSidebar(group, tags) {
  const sidebarPath = path.join(__dirname, '../.vitepress/config/zh.mts');
  let sidebarContent = fs.readFileSync(sidebarPath, 'utf8');
  
  // 生成模块链接
  const moduleLinks = tags.map(tag => {
    const moduleName = tag.name.toLowerCase().replace(/\s+/g, '-');
    return `            { link: 'openapi/api/${group.outputDir}/${moduleName}', text: '${tag.name} API' }`;
  }).join(',\n');
  
  // 更新侧边栏配置
  const sidebarPattern = new RegExp(`(text: '${group.name}',\\s*items: \\[\\s*\\{[^}]+\\},?\\s*)(\\])`, 's');
  const replacement = `$1,\n${moduleLinks}\n        $2`;
  
  if (sidebarContent.match(sidebarPattern)) {
    sidebarContent = sidebarContent.replace(sidebarPattern, replacement);
    fs.writeFileSync(sidebarPath, sidebarContent, 'utf8');
    console.log(`侧边栏配置已更新: ${group.name}`);
  }
}

/**
 * 主函数
 */
async function main() {
  console.log('开始自动生成 API 文档...\n');

  for (const [key, group] of Object.entries(config.apiGroups)) {
    console.log(`处理 ${group.name}...`);
    
    // 获取 Swagger JSON（统一）
    const swaggerData = await getSwaggerJson(group);
    if (!swaggerData) {
      console.log(`跳过 ${group.name}，无法获取数据\n`);
      continue;
    }

    // 基于分组前缀过滤 paths
    const filterByPrefix = (doc, prefix) => {
      const cloned = JSON.parse(JSON.stringify(doc));
      const filteredPaths = {};
      Object.keys(cloned.paths || {}).forEach((p) => {
        if (p.startsWith(prefix)) filteredPaths[p] = cloned.paths[p];
      });
      cloned.paths = filteredPaths;
      return cloned;
    };

    const filtered = filterByPrefix(swaggerData, group.prefix + '/');

    // 生成概览文档
    const overviewContent = generateOverview(group);
    const overviewPath = path.join(config.docsDir, group.outputDir, 'index.md');
    saveDocument(overviewPath, overviewContent);

    // 按标签生成模块文档
    const tags = filtered.tags || [];
    const paths = filtered.paths || {};

    for (const tag of tags) {
      const moduleName = tag.name.toLowerCase().replace(/\s+/g, '-');
      const moduleContent = generateModuleDoc(group, tag, paths);
      const modulePath = path.join(config.docsDir, group.outputDir, `${moduleName}.md`);
      saveDocument(modulePath, moduleContent);
    }

    // 更新侧边栏配置
    updateSidebar(group, tags);
    
    console.log(`${group.name} 处理完成\n`);
  }

  console.log('API 文档自动生成完成！');
  console.log('\n下一步：');
  console.log('1. 启动文档服务: npm run dev');
  console.log('2. 访问: http://localhost:6173/wwjcloud/openapi/api/');
}

// 运行脚本
if (require.main === module) {
  main().catch(error => {
    console.error('脚本执行失败:', error);
    process.exit(1);
  });
}

module.exports = {
  config,
  getSwaggerJson,
  generateOverview,
  generateModuleDoc,
  saveDocument,
  updateSidebar
}; 