import 'dotenv/config';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
// 新增导入
import { CacheModule } from '@nestjs/cache-manager';
import { ScheduleModule } from '@nestjs/schedule';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';
import { TerminusModule } from '@nestjs/terminus';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
import 'winston-daily-rotate-file';
import * as Joi from 'joi';
import { ClsModule } from 'nestjs-cls';
import { VendorModule } from './vendor';
import { 
  SettingsModule, 
  UploadModule, 
  AuthModule,
  MemberModule,
  AdminModule,
  RbacModule,
  GlobalAuthGuard,
  RolesGuard
} from './common';
import { ServeStaticModule } from '@nestjs/serve-static';
import * as path from 'path';

// 允许通过环境变量禁用数据库初始化（用于本地开发或暂时无数据库时）
const dbImports =
  process.env.DB_DISABLE === 'true'
    ? []
    : [
        TypeOrmModule.forRootAsync({
          inject: [ConfigService],
          useFactory: (config: ConfigService) => ({
            type: 'mysql',
            host: config.get('db.host', 'localhost'),
            port: config.get('db.port', 3306),
            username: config.get('db.username', 'root'),
            password: config.get('db.password', ''),
            database: config.get('db.database', 'wwjcloud'),
            autoLoadEntities: true,
            synchronize: false,
          }),
        }),
      ];

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [configuration],
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test')
          .default('development'),
        PORT: Joi.number().default(3000),
        DB_HOST: Joi.string().default('localhost'),
        DB_PORT: Joi.number().default(3306),
        DB_USERNAME: Joi.string().default('root'),
        DB_PASSWORD: Joi.string().allow('').default(''),
        DB_DATABASE: Joi.string().default('wwjcloud'),
        REDIS_HOST: Joi.string().default('localhost'),
        REDIS_PORT: Joi.number().default(6379),
        REDIS_PASSWORD: Joi.string().allow('').default(''),
        JWT_SECRET: Joi.string().default('change_me'),
        JWT_EXPIRES_IN: Joi.string().default('7d'),
        UPLOAD_PATH: Joi.string().default('public/upload'),
        STORAGE_PROVIDER: Joi.string()
          .valid(
            'local',
            'tencent',
            'aliyun',
            'qiniu',
            'alists3',
            'webdav',
            'ftp',
          )
          .default('local'),
        PAYMENT_PROVIDER: Joi.string()
          .valid('wechat', 'alipay')
          .default('alipay'),
        LOG_LEVEL: Joi.string().default('info'),
        THROTTLE_TTL: Joi.number().default(60),
        THROTTLE_LIMIT: Joi.number().default(100),
      }),
    }),
    // 静态资源托管：仅暴露 /upload/**
    ServeStaticModule.forRoot({
      rootPath: path.resolve(process.cwd(), 'public', 'upload'),
      serveRoot: '/upload',
    }),
    // 缓存（内存实现，后续可替换为 redis-store）
    CacheModule.register({ isGlobal: true }),
    // 计划任务
    ScheduleModule.forRoot(),
    // 事件总线
    EventEmitterModule.forRoot(),
    // 限流
    ThrottlerModule.forRoot([
      {
        ttl: Number(process.env.THROTTLE_TTL) || 60,
        limit: Number(process.env.THROTTLE_LIMIT) || 100,
      },
    ]),
    // 健康检查（需要时可增加控制器）
    TerminusModule,
    // 日志
    WinstonModule.forRoot({
      level: process.env.LOG_LEVEL || 'info',
      transports: [
        new winston.transports.Console({
          format: winston.format.combine(
            winston.format.timestamp(),
            winston.format.colorize(),
            winston.format.printf(({ level, message, timestamp, context }) => {
              return `${timestamp} [${level}]${context ? ' [' + context + ']' : ''} ${message}`;
            }),
          ),
        }),
        new (winston.transports as any).DailyRotateFile({
          dirname: 'logs',
          filename: 'app-%DATE%.log',
          datePattern: 'YYYY-MM-DD',
          zippedArchive: false,
          maxFiles: '14d',
          level: process.env.LOG_LEVEL || 'info',
        }),
      ],
    }),
    // 请求上下文
    ClsModule.forRoot({
      global: true,
      middleware: { mount: true },
    }),
    // 数据库（可通过 DB_DISABLE=true 禁用）
    ...dbImports,
    // Vendor 绑定 Core 抽象到具体适配器
    VendorModule,
    // Common 编排服务（聚合到 SettingsModule 下）
    SettingsModule,
    // 上传模块（提供 /upload/file /upload/files 接口）
    UploadModule,
    // 用户管理模块
    MemberModule,
    AdminModule,
    // 权限管理模块
    RbacModule,
    // 认证模块（提供 super/admin/auth 登录分流）
    AuthModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
    // 全局守卫
    { provide: APP_GUARD, useClass: ThrottlerGuard },
    { provide: APP_GUARD, useClass: GlobalAuthGuard },
    { provide: APP_GUARD, useClass: RolesGuard },
  ],
})
export class AppModule {}
