import { execFileSync } from 'node:child_process';
import { mkdirSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import path from 'node:path';

const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const openApiUrl = process.env.OPENAPI_URL || 'http://localhost:5090/openapi/v1.json';
const response = await fetch(openApiUrl);
if (!response.ok) throw new Error(`OpenAPI 下载失败：${response.status} ${response.statusText}`);
const document = await response.json();

const generatedDir = path.join(projectRoot, '.generated');
const apiDir = path.join(projectRoot, 'src', 'api');
mkdirSync(generatedDir, { recursive: true });
mkdirSync(apiDir, { recursive: true });
const snapshotPath = path.join(generatedDir, 'openapi.json');
writeFileSync(snapshotPath, `${JSON.stringify(document)}\n`);

const cli = path.join(projectRoot, 'node_modules', '.bin', process.platform === 'win32' ? 'openapi-typescript.cmd' : 'openapi-typescript');
execFileSync(cli, [snapshotPath, '-o', path.join(apiDir, 'schema.generated.d.ts')], { stdio: 'inherit' });

const methods = new Set(['get', 'post', 'put', 'patch', 'delete']);
const operations = [];
for (const [route, pathItem] of Object.entries(document.paths || {})) {
  for (const [method, operation] of Object.entries(pathItem || {})) {
    if (!methods.has(method)) continue;
    const tags = operation.tags || [];
    const isPlatform = (route.startsWith('/api/platform/') || route === '/api/platform') &&
      !route.startsWith('/api/platform/auth/');
    if (!isPlatform) continue;
    const requestSchema = operation.requestBody?.content?.['application/json']?.schema || null;
    const responseEntry = Object.entries(operation.responses || {}).find(([status]) => /^2/.test(status));
    const responseSchema = responseEntry?.[1]?.content?.['application/json']?.schema || null;
    operations.push({
      id: `${method.toUpperCase()} ${route}`,
      method: method.toUpperCase(),
      path: route,
      tag: tags[0] || '平台端',
      summary: operation.summary || `${method.toUpperCase()} ${route}`,
      description: operation.description || '',
      parameters: [...(pathItem.parameters || []), ...(operation.parameters || [])],
      requestSchema,
      responseSchema,
      requiredPermission: operation['x-tiku-required-permission'] || null,
      riskLevel: operation['x-tiku-risk-level'] || (method === 'get' ? 'low' : 'medium'),
      approvalPolicyCode: operation['x-tiku-approval-policy-code'] || null,
    });
  }
}

operations.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
const schemas = document.components?.schemas || {};
const source = `/* eslint-disable */\n// 由 scripts/generate-platform-operations.mjs 根据后端 OpenAPI 自动生成，请勿手改。\nimport type { PlatformOperation } from './types';\n\nexport const platformOperations = ${JSON.stringify(operations, null, 2)} as const satisfies readonly PlatformOperation[];\nexport const openApiSchemas = ${JSON.stringify(schemas, null, 2)} as const;\n`;
writeFileSync(path.join(apiDir, 'platform-operations.generated.ts'), source);
console.log(`已生成 ${operations.length} 个平台接口契约，来源：${openApiUrl}`);
