const swagger = require("../../_docs/swagger.json");
const auth = require("../service/biz_auth_verify");
const proxy = require("../service/biz_proxy_service");



/**
 * 从 ctx 请求头中提取 Token（不含 query）
 * - Authorization: Bearer <token>
 * - Authorization: <token>（无 Bearer 前缀时整段作为 token）
 * - X-Api-Token / X-Token
 */
function extractToken(ctx) {

  let x_token = ctx.headers['authorization'] || ''
  if (x_token.startsWith("Bearer ")) {
    x_token = x_token.slice(7).trim();
  }
  return x_token;
}

/**
 * 提取 swagger tags 第一项作为 feature 名（用于套餐功能点校验）
 */
function pickFeature(spec) {
  if (spec.tags && spec.tags.length > 0) {
    return spec.tags[0];
  }
  return null;
}

/** 不参与转发的文档路径（与 framework 实际路由重叠或仅为说明） */
function should_skip_proxy_path(route_path) {
  return (
    route_path.startsWith("/admin_api") ||
    route_path.startsWith("/api/auth")
  );
}

/**
 * 构建转发路由表（供 framework.addRoutes 注册）
 */
function buildProxyRoutes() {
  const routes = {};

  for (const [path, methods] of Object.entries(swagger.paths)) {
    if (should_skip_proxy_path(path)) {
      continue;
    }
    for (const [method, spec] of Object.entries(methods)) {
      const routeKey = `${method.toUpperCase()} ${path}`;

      routes[routeKey] = async (ctx) => {
        // 1. 提取 Token
        const token = extractToken(ctx);
        if (!token) {
          ctx.fail("缺少 Token");
          return;
        }

        // 2. 鉴权：Token + 用户 + 订阅 + 套餐功能点 + 接口权限 + 调用量
        const feature = pickFeature(spec);
        const authResult = await auth.verifyRequest({ token, feature, api_path: path });
        if (!authResult.ok) {
          ctx.fail(authResult.message || "鉴权失败");
          return;
        }
        // 3. 组装 query，并注入 token 对应 key（上游要求参数名为 key）
        const query = { ...ctx.query };
        if (!query.key && authResult.context && authResult.context.token_key) {
          query.key = authResult.context.token_key;
        }

        // 4. 转发到上游
        const result = await proxy.forwardRequest({
          api_path: path,
          method: method.toUpperCase(),
          query,
          body: ctx.getBody(),
          headers: ctx.headers || {},
          auth_ctx: authResult.context,
        });

        // 5. 根据上游 Success 字段决定响应方式
        const upstream = result.data;
        if (upstream && upstream.Code === 200) {
          ctx.success(upstream);
        } else {
          ctx.fail(upstream && upstream.Text ? upstream.Text : "上游请求失败", upstream);
        }
      };
    }
  }

  return routes;
}

module.exports = { buildProxyRoutes };
