import 'dotenv/config';
import { mkdirSync } from 'node:fs';
import { BadRequestException, ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module.js';
import { HttpExceptionFilter } from './common/http-exception.filter.js';
import { MESSAGES } from './common/messages.js';
import { ResponseEnvelopeInterceptor } from './common/response-envelope.interceptor.js';
import { resolveUploadRootDir } from './uploads/upload-path.util.js';

async function bootstrap() {
  // 创建应用实例并加载核心模块。
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.enableCors();
  mkdirSync(resolveUploadRootDir(), { recursive: true });
  app.useStaticAssets(resolveUploadRootDir(), {
    prefix: '/uploads/',
  });
  // 全局校验：清理未知字段、自动类型转换，并将校验错误统一为中文信息。
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
      forbidNonWhitelisted: true,
      exceptionFactory: (errors) => {
        const messages = errors
          .flatMap((error) => Object.values(error.constraints ?? {}))
          .filter((item): item is string => Boolean(item));
        return new BadRequestException(
          messages.length > 0
            ? messages.join('；')
            : MESSAGES.DEFAULT_BAD_REQUEST,
        );
      },
    }),
  );

  // 全局异常与成功响应统一格式化。
  app.useGlobalFilters(new HttpExceptionFilter());
  app.useGlobalInterceptors(new ResponseEnvelopeInterceptor());

  // Swagger 文档：提供在线调试与 OpenAPI JSON 导出。
  const swaggerConfig = new DocumentBuilder()
    .setTitle('TYT 多租户医疗调压系统 API')
    .setDescription('后端接口文档（含认证、RBAC、任务流转与患者聚合）')
    .setVersion('1.0.0')
    .addServer('http://192.168.0.140:3000', 'localhost')
    .addBearerAuth(
      {
        type: 'http',
        scheme: 'bearer',
        bearerFormat: 'JWT',
        description: '在此输入登录接口返回的 accessToken',
      },
      'bearer',
    )
    .build();

  const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig);
  SwaggerModule.setup('api/docs', app, swaggerDocument, {
    jsonDocumentUrl: 'api/docs-json',
  });

  // 启动 HTTP 服务。
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
