import type { NestFastifyApplication } from '@nestjs/platform-fastify';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import type { ParameterObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
import { isObject } from 'class-validator';

/** 注册 Swagger */
export function useSwaggerConfig(app: NestFastifyApplication, ipv4: string, port: number) {
  const config = new DocumentBuilder()
    .setTitle('API文档')
    .setDescription('Test01移动端(小程序/APP/移动网页)文档')
    .setVersion('1.0')
    .setContact('马小平', '', 'mxp131011@qq.com')
    .setLicense('MIT', 'https://opensource.org/licenses/MIT')
    .addServer('https://meeting.qyzhjy.com', '生产环境')
    .addServer(`http://${ipv4}:${port}`, '测试环境')
    // JWT Bearer 认证
    .addBearerAuth(
      { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', description: '使用 JWT Token 进行鉴权', in: 'header' },
      'JWT-auth' // 安全方案名称
    )
    // 全局启用 JWT 认证（所有接口默认需要认证）
    .addSecurityRequirements('JWT-auth');

  /** 全局参数 */
  const list: Omit<ParameterObject, 'example' | 'examples'>[] = [
    {
      name: 'Custom-Mac',
      in: 'header',
      description: '设备id,设备的唯一识别码',
      required: true,
      schema: { type: 'string', default: '165362158044846585135' },
    },
    {
      name: 'Custom-Timestamp',
      in: 'header',
      description: '时间戳(毫秒)',
      required: true,
      schema: { type: 'string', default: 1772768634072 },
    },
    {
      name: 'Custom-Platform',
      in: 'header',
      description: '设备平台如:ios/android/web',
      required: true,
      schema: { type: 'string', default: 'WECHAT', enum: ['WECHAT', 'PC', 'WEB', 'WECHAT', 'PC-APP'] },
    },
  ];

  config.addGlobalParameters(...list);
  // 创建 Swagger 文档
  const document = SwaggerModule.createDocument(app, config.build());

  /** 设置 Swagger 路径 */
  SwaggerModule.setup('api-docs', app, document, {
    jsonDocumentUrl: 'api-docs/swagger.json',
    /**
     * 重写请求时的文档处理逻辑
     */
    patchDocumentOnRequest(req: any, _res, docs) {
      // 动态更新时间戳参数的 default 值为当前时间戳
      if (docs.components?.parameters) {
        const timestampParam = docs.components.parameters['Custom-Timestamp'];
        // 检查是否为 ParameterObject（而非 ReferenceObject）
        if (timestampParam && 'schema' in timestampParam && timestampParam.schema) {
          (timestampParam.schema as Record<string, unknown>).default = String(Date.now());
        }
      }
      // 判断是否是 YAML 文档请求，并且是否存在 paths 属性
      if (req.url.includes('api-docs/swagger.json') && isObject(docs.paths)) {
        // 遍历 paths 对象的所有属性（即路径）
        for (const path of Object.keys(docs.paths)) {
          const methods = docs.paths[path]! as Record<string, unknown>;
          for (const method of Object.keys(methods)) {
            if (isObject(methods[method]) && 'parameters' in methods[method]) {
              const parameters = methods[method].parameters;
              if (Array.isArray(parameters)) {
                methods[method].parameters = parameters.filter((item: Record<string, unknown>) => {
                  // 提取全局参数的名称
                  const keys = list.map((item2) => item2.name);
                  // 过滤掉名称在全局参数名称列表中的参数
                  return !(isObject(item) && keys.includes(String(item?.name || '')));
                });
              }
            }
          }
        }
      }
      return docs;
    },
  });
}
