#!/usr/bin/env node

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');

// CRUD操作映射
const CRUD_OPERATIONS = {
  list: { method: 'POST', path: '/list', description: '获取列表' },
  detail: { method: 'GET', path: '/detail', description: '获取详情' },
  add: { method: 'POST', path: '/add', description: '新增' },
  edit: { method: 'PUT', path: '/update', description: '更新' },
  delete: { method: 'DELETE', path: '/delete', description: '删除' },
  export: { method: 'GET', path: '/export', description: '导出' },
  report: { method: 'GET', path: '/report', description: '报表' },
};

// 扫描所有service文件
function scanServiceFiles(dir) {
  const serviceFiles = [];

  function scanDirectory(currentDir) {
    const items = fs.readdirSync(currentDir, { withFileTypes: true });

    for (const item of items) {
      const fullPath = path.join(currentDir, item.name);

      if (item.isDirectory()) {
        scanDirectory(fullPath);
      } else if (
        item.name.endsWith('.service.js') ||
        (item.name === 'index.js' && (fullPath.includes('/api/') || fullPath.includes('\\api\\')))
      ) {
        serviceFiles.push({
          path: fullPath,
          relativePath: path.relative(projectRoot, fullPath),
          moduleName: extractModuleName(fullPath),
        });
      }
    }
  }

  scanDirectory(dir);
  return serviceFiles;
}

// 提取模块名称
function extractModuleName(filePath) {
  const parts = filePath.split(path.sep);

  // 对于 .service.js 文件
  const serviceIndex = parts.findIndex((part) => part.endsWith('.service.js'));
  if (serviceIndex > 0) {
    return parts[serviceIndex - 1];
  }

  // 对于 api/index.js 文件
  const apiIndex = parts.findIndex((part) => part === 'api');
  if (apiIndex > 0 && parts[apiIndex + 1] === 'index.js') {
    // 取api目录的上一级目录作为模块名
    return parts[apiIndex - 1];
  }

  return path.basename(filePath, '.js');
}

// 解析service文件内容
async function parseServiceFile(filePath) {
  try {
    const content = fs.readFileSync(filePath, 'utf-8');

    // 提取API对象 - 支持多种格式
    let apiContent = null;

    // 格式1: const api = {...};
    let apiMatch = content.match(/const api = \{([\s\S]*?)\};/);
    if (apiMatch) {
      apiContent = apiMatch[1];
    } else {
      // 格式2: export default {...}
      apiMatch = content.match(/export default \{([\s\S]*?)\};?$/m);
      if (apiMatch) {
        apiContent = apiMatch[1];
      }
    }

    if (!apiContent) {
      return null;
    }

    const apis = parseApiContent(apiContent, filePath);

    return {
      filePath,
      apis,
    };
  } catch (error) {
    console.error(`解析文件失败 ${filePath}:`, error.message);
    return null;
  }
}

// 解析API内容
function parseApiContent(content, filePath) {
  const apis = [];

  // 首先解析嵌套的API结构
  const nestedApiRegex = /(\w+):\s*\{([\s\S]*?)(?=\w+:\s*\{|$)/g;
  let match;

  while ((match = nestedApiRegex.exec(content)) !== null) {
    const [, apiName, apiBody] = match;
    // 检查是否包含CRUD或方法定义
    if (apiBody.includes('CRUD') || apiBody.includes('=>') || apiBody.includes('request(')) {
      const cleanApiBody = apiBody.replace(/,\s*$/, '').trim();
      const apiInfo = parseApiBody(apiName, cleanApiBody, filePath);
      if (apiInfo) {
        apis.push(apiInfo);
      }
    }
  }

  // 同时解析顶层方法
  const topLevelEndpoints = parseCustomEndpoints(content);
  if (topLevelEndpoints.length > 0) {
    const topLevelApi = {
      name: 'api',
      endpoints: topLevelEndpoints,
    };
    apis.push(topLevelApi);
  }

  return apis;
}

// 解析API主体
function parseApiBody(apiName, body, filePath) {
  const api = {
    name: apiName,
    endpoints: [],
  };

  // 检查是否使用CRUD
  const crudMatch = body.match(/\.\.\.CRUD\(['"`]([^'"`]+)['"`](?:,\s*\[([^\]]*)\])?\)/);
  if (crudMatch) {
    const [, basePath, methodsStr] = crudMatch;
    const methods = methodsStr
      ? methodsStr.split(',').map((m) => m.trim().replace(/['"`]/g, ''))
      : ['list', 'detail', 'add', 'edit', 'delete'];

    // 添加CRUD端点
    methods.forEach((method) => {
      if (CRUD_OPERATIONS[method]) {
        const operation = CRUD_OPERATIONS[method];
        const fullUrl = basePath + operation.path;

        // 过滤掉以 shop/admin/ 开头的接口
        if (!fullUrl.startsWith('shop/admin/')) {
          api.endpoints.push({
            name: method,
            method: operation.method,
            url: fullUrl,
            description: operation.description,
            type: 'CRUD',
          });
        }
      }
    });
  }

  // 解析自定义端点
  const customEndpoints = parseCustomEndpoints(body);
  api.endpoints.push(...customEndpoints);

  return api.endpoints.length > 0 ? api : null;
}

// 解析自定义端点
function parseCustomEndpoints(body) {
  const endpoints = [];

  // 匹配自定义方法 - 支持多行格式
  const methodPattern = /(\w+):\s*\([^)]*\)\s*=>\s*([\s\S]*?)(?=,\s*\w+:|$)/g;
  let match;

  while ((match = methodPattern.exec(body)) !== null) {
    const [, methodName, methodBody] = match;

    // 跳过已知的CRUD方法和展开操作
    if (
      ['list', 'detail', 'add', 'edit', 'delete', 'export', 'report'].includes(methodName) ||
      methodBody.includes('...CRUD')
    ) {
      continue;
    }

    // 解析request调用
    const requestMatch = methodBody.match(/request\(\{([\s\S]*?)\}\)/);
    if (requestMatch) {
      const requestConfig = requestMatch[1];

      // 提取URL和方法
      const urlMatch = requestConfig.match(/url:\s*['"`]([^'"`]+)['"`]/);
      const methodMatch = requestConfig.match(/method:\s*['"`]([^'"`]+)['"`]/);

      if (urlMatch) {
        const url = urlMatch[1];

        // 过滤掉以 shop/admin/ 开头的接口
        if (!url.startsWith('shop/admin/')) {
          const description = generateMethodDescription(methodName);

          endpoints.push({
            name: methodName,
            method: methodMatch ? methodMatch[1] : 'GET',
            url: url,
            description,
            type: 'Custom',
          });
        }
      }
    }

    // 解析SELECT调用
    const selectMatch = methodBody.match(/SELECT\(['"`]([^'"`]+)['"`]/);
    if (selectMatch) {
      const url = selectMatch[1] + '/select';

      // 过滤掉以 shop/admin/ 开头的接口
      if (!url.startsWith('shop/admin/')) {
        endpoints.push({
          name: methodName,
          method: 'GET',
          url: url,
          description: generateMethodDescription(methodName),
          type: 'Custom',
        });
      }
    }
  }

  return endpoints;
}

// 生成方法描述
function generateMethodDescription(methodName) {
  const descriptions = {
    batchShowStatus: '批量上下架商品',
    getStatusNum: '获取商品状态数量',
    select: '选择列表',
    getType: '获取类型',
    dispatch: '发货',
    dispatchByUpload: '上传发货单发货',
    total: '获取总览数据',
    ranking: '获取排行数据',
    chart: '获取图表数据',
    getStats: '获取统计数据',
    userDetail: '获取用户详情',
    myUsers: '获取我的用户',
    getUserAddresses: '获取用户地址',
    share: '分享相关',
    coupon: '优惠券相关',
    couponList: '优惠券列表',
  };

  return descriptions[methodName] || `自定义接口 - ${methodName}`;
}

// 生成Markdown文档
function generateMarkdown(serviceData) {
  let markdown = `# 系统API接口文档\n\n`;
  markdown += `> 自动生成时间: ${new Date().toLocaleString('zh-CN')}\n\n`;
  markdown += `## 📋 目录\n\n`;

  // 生成目录
  serviceData.forEach((service, index) => {
    markdown += `${index + 1}. [${service.moduleName}模块](#${index + 1}-${service.moduleName}模块)\n`;
  });

  markdown += `\n---\n\n`;

  // 生成详细内容
  serviceData.forEach((service, index) => {
    markdown += `## ${index + 1}. ${service.moduleName}模块\n\n`;
    markdown += `**文件路径**: \`${service.relativePath}\`\n\n`;

    if (service.data && service.data.apis) {
      service.data.apis.forEach((api) => {
        markdown += `### ${api.name}\n\n`;

        if (api.endpoints.length > 0) {
          markdown += `| 接口名称 | 请求方法 | 接口地址 | 说明 | 类型 |\n`;
          markdown += `|---------|---------|---------|------|------|\n`;

          api.endpoints.forEach((endpoint) => {
            markdown += `| ${endpoint.name} | ${endpoint.method} | ${endpoint.url} | ${endpoint.description} | ${endpoint.type} |\n`;
          });

          markdown += `\n`;
        }
      });
    }

    markdown += `---\n\n`;
  });

  // 添加统计信息
  const totalApis = serviceData.reduce((total, service) => {
    if (service.data && service.data.apis) {
      return (
        total + service.data.apis.reduce((apiTotal, api) => apiTotal + api.endpoints.length, 0)
      );
    }
    return total;
  }, 0);

  markdown += `## 📊 统计信息\n\n`;
  markdown += `- **模块总数**: ${serviceData.length}\n`;
  markdown += `- **接口总数**: ${totalApis}\n`;
  markdown += `- **生成时间**: ${new Date().toLocaleString('zh-CN')}\n\n`;

  return markdown;
}

// 主函数
async function main() {
  console.log('🔍 开始扫描API接口文件...\n');

  // 扫描service文件
  const srcDir = path.join(projectRoot, 'src');
  const serviceFiles = scanServiceFiles(srcDir);

  console.log(`📁 找到 ${serviceFiles.length} 个service文件:\n`);
  serviceFiles.forEach((file) => {
    console.log(`  - ${file.relativePath} (${file.moduleName})`);
  });

  console.log('\n🔄 开始解析API定义...\n');

  // 解析每个service文件
  const serviceData = [];
  for (const file of serviceFiles) {
    console.log(`正在解析: ${file.relativePath}`);
    const data = await parseServiceFile(file.path);

    serviceData.push({
      ...file,
      data,
    });
  }

  console.log('\n📝 生成API文档...\n');

  // 生成文档
  const markdown = generateMarkdown(serviceData);

  // 保存文档
  const outputPath = path.join(projectRoot, 'docs', 'api-interfaces.md');

  // 确保docs目录存在
  const docsDir = path.dirname(outputPath);
  if (!fs.existsSync(docsDir)) {
    fs.mkdirSync(docsDir, { recursive: true });
  }

  fs.writeFileSync(outputPath, markdown, 'utf-8');

  console.log(`✅ API文档生成完成!`);
  console.log(`📄 文档路径: ${outputPath}`);
  console.log(`📊 统计信息:`);
  console.log(`   - 模块数量: ${serviceData.length}`);

  const totalApis = serviceData.reduce((total, service) => {
    if (service.data && service.data.apis) {
      return (
        total + service.data.apis.reduce((apiTotal, api) => apiTotal + api.endpoints.length, 0)
      );
    }
    return total;
  }, 0);

  console.log(`   - 接口数量: ${totalApis}`);
}

main().catch(console.error);
