/**
 * 用户档案模块
 *
 * 功能描述：
 * - 提供用户档案数据访问的完整模块配置
 * - 支持MySQL和内存两种存储模式的动态切换
 * - 集成TypeORM实体和服务的依赖注入
 * - 为位置广播系统提供数据持久化支持
 *
 * 职责分离：
 * - 模块配置：定义模块的导入、提供者和导出
 * - 依赖注入：配置服务和存储库的注入关系
 * - 存储模式：支持数据库和内存两种存储实现
 * - 接口抽象：提供统一的服务接口供业务层使用
 *
 * 存储模式：
 * - 数据库模式：使用TypeORM连接MySQL数据库
 * - 内存模式：使用Map存储，适用于开发和测试
 *
 * 最近修改：
 * - 2026-01-08: 功能新增 - 创建用户档案模块，支持位置广播系统 (修改者: moyin)
 *
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { Module, DynamicModule, Global } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserProfiles } from './user_profiles.entity';
import { UserProfilesService } from './user_profiles.service';
import { UserProfilesMemoryService } from './user_profiles_memory.service';

/**
 * 用户档案模块类
 *
 * 职责：
 * - 配置用户档案相关的服务和实体
 * - 提供数据库和内存两种存储模式
 * - 支持动态模块配置和依赖注入
 * - 为位置广播系统提供数据访问层
 *
 * 模块特性：
 * - 动态模块：支持运行时配置选择
 * - 双模式支持：数据库模式和内存模式
 * - 接口统一：提供一致的服务接口
 * - 可测试性：内存模式便于单元测试
 *
 * 使用场景：
 * - 生产环境：使用数据库模式，数据持久化
 * - 开发测试：使用内存模式，快速启动
 * - 单元测试：使用内存模式，隔离测试
 * - 故障降级：数据库故障时切换到内存模式
 */
@Global()
@Module({})
export class UserProfilesModule {

  /**
   * 配置数据库模式的用户档案模块
   *
   * 功能描述：
   * 创建使用MySQL数据库的用户档案模块配置
   *
   * 技术实现：
   * 1. 导入TypeORM模块并注册UserProfiles实体
   * 2. 提供UserProfilesService作为数据访问服务
   * 3. 导出服务供其他模块使用
   * 4. 配置依赖注入关系
   *
   * 适用场景：
   * - 生产环境部署
   * - 需要数据持久化的场景
   * - 多实例部署的数据共享
   * - 大数据量的用户档案管理
   *
   * @returns 配置了数据库模式的动态模块
   *
   * @example
   * ```typescript
   * // 在AppModule中使用数据库模式
   * @Module({
   *   imports: [
   *     UserProfilesModule.forDatabase(),
   *     // 其他模块...
   *   ],
   * })
   * export class AppModule {}
   * ```
   */
  static forDatabase(): DynamicModule {
    return {
      module: UserProfilesModule,
      imports: [
        // 导入TypeORM模块，注册UserProfiles实体
        TypeOrmModule.forFeature([UserProfiles])
      ],
      providers: [
        // 提供MySQL数据库实现的用户档案服务
        UserProfilesService,
        {
          // 使用接口名称作为注入令牌，便于依赖注入
          provide: 'IUserProfilesService',
          useClass: UserProfilesService,
        },
      ],
      exports: [
        // 导出服务供其他模块使用
        UserProfilesService,
        'IUserProfilesService',
      ],
    };
  }

  /**
   * 配置内存模式的用户档案模块
   *
   * 功能描述：
   * 创建使用内存存储的用户档案模块配置
   *
   * 技术实现：
   * 1. 提供UserProfilesMemoryService作为内存存储服务
   * 2. 使用Map数据结构进行内存数据管理
   * 3. 导出服务供其他模块使用
   * 4. 配置统一的服务接口
   *
   * 适用场景：
   * - 开发环境快速启动
   * - 单元测试和集成测试
   * - 演示和原型开发
   * - 数据库故障时的降级方案
   *
   * 性能特点：
   * - 启动速度快，无需数据库连接
   * - 读写性能高，直接内存访问
   * - 数据易失，重启后数据丢失
   * - 内存占用，大数据量时需注意
   *
   * @returns 配置了内存模式的动态模块
   *
   * @example
   * ```typescript
   * // 在测试模块中使用内存模式
   * @Module({
   *   imports: [
   *     UserProfilesModule.forMemory(),
   *     // 其他测试模块...
   *   ],
   * })
   * export class TestModule {}
   * ```
   */
  static forMemory(): DynamicModule {
    return {
      module: UserProfilesModule,
      providers: [
        // 提供内存存储实现的用户档案服务
        UserProfilesMemoryService,
        {
          // 使用接口名称作为注入令牌，保持接口一致性
          provide: 'IUserProfilesService',
          useClass: UserProfilesMemoryService,
        },
      ],
      exports: [
        // 导出服务供其他模块使用
        UserProfilesMemoryService,
        'IUserProfilesService',
      ],
    };
  }

  /**
   * 根据配置自动选择存储模式
   *
   * 功能描述：
   * 根据环境变量或配置参数自动选择数据库或内存模式
   *
   * 技术实现：
   * 1. 读取环境变量或配置参数
   * 2. 根据配置选择对应的存储模式
   * 3. 返回相应的动态模块配置
   * 4. 支持运行时模式切换
   *
   * 配置规则：
   * - DB_HOST存在且不为空：使用数据库模式
   * - DB_HOST不存在或为空：使用内存模式
   * - NODE_ENV=test：强制使用内存模式
   * - USE_MEMORY_STORAGE=true：强制使用内存模式
   *
   * @param useMemory 是否强制使用内存模式（可选）
   * @returns 自动选择的动态模块配置
   *
   * @example
   * ```typescript
   * // 在AppModule中使用自动模式选择
   * @Module({
   *   imports: [
   *     UserProfilesModule.forRoot(),
   *     // 其他模块...
   *   ],
   * })
   * export class AppModule {}
   *
   * // 强制使用内存模式
   * UserProfilesModule.forRoot(true);
   * ```
   */
  static forRoot(useMemory?: boolean): DynamicModule {
    // 自动检测存储模式
    const shouldUseMemory = useMemory ?? (
      process.env.NODE_ENV === 'test' ||
      process.env.USE_MEMORY_STORAGE === 'true' ||
      !process.env.DB_HOST
    );

    // 根据检测结果选择对应的模块配置
    if (shouldUseMemory) {
      return this.forMemory();
    } else {
      return this.forDatabase();
    }
  }
}
