/**
 * 用户内存存储服务类
 * 
 * 功能描述：
 * - 提供基于内存的用户数据存储技术实现
 * - 作为数据库连接失败时的回退方案
 * - 实现与UsersService相同的接口
 * - 支持完整的CRUD操作和数据管理
 * 
 * 职责分离：
 * - 数据存储：使用Map进行内存数据管理
 * - ID生成：线程安全的自增ID生成机制
 * - 数据验证：数据完整性和唯一性约束检查
 * - 异常处理：统一的错误处理和日志记录
 * 
 * 使用场景：
 * - 开发环境无数据库时的快速启动
 * - 测试环境的轻量级存储
 * - 数据库故障时的临时降级
 * 
 * 注意事项：
 * - 数据仅存储在内存中，重启后丢失
 * - 不适用于生产环境
 * - 性能优异但无持久化保证
 * 
 * 最近修改：
 * - 2026-01-08: 架构分层优化 - 修正导入路径，确保Core层不依赖Business层 (修改者: moyin)
 * - 2026-01-08: 代码质量优化 - 重构create方法，提取私有方法减少代码重复 (修改者: moyin)
 * - 2026-01-07: 代码规范优化 - 完善注释规范，添加完整的文件头和方法注释
 * - 2026-01-07: 功能新增 - 添加createWithDuplicateCheck方法，保持与数据库服务一致
 * - 2026-01-07: 功能优化 - 添加日志记录系统，统一异常处理和性能监控
 * 
 * @author moyin
 * @version 1.0.3
 * @since 2025-12-17
 * @lastModified 2026-01-08
 */

import { Injectable, ConflictException, NotFoundException, BadRequestException } from '@nestjs/common';
import { Users } from './users.entity';
import { CreateUserDto } from './users.dto';
import { UserStatus } from './user_status.enum';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';
import { BaseUsersService } from './base_users.service';
import { USER_ROLES, QUERY_LIMITS, SYSTEM_CONFIG, ERROR_MESSAGES, DATABASE_CONSTANTS, ValidationUtils, PerformanceMonitor } from './users.constants';

@Injectable()
export class UsersMemoryService extends BaseUsersService {
  private users: Map<bigint, Users> = new Map();
  private CURRENT_ID: bigint = BigInt(USER_ROLES.NORMAL_USER);
  private readonly ID_LOCK = new Set<string>(); // 简单的ID生成锁

  constructor() {
    super(); // 调用基类构造函数
  }

  /**
   * 根据条件查找用户
   * 
   * @param predicate 查找条件
   * @returns 匹配的用户或null
   */
  private findUserByCondition(predicate: (user: Users) => boolean): Users | null {
    const user = Array.from(this.users.values()).find(predicate);
    return user || null;
  }

  /**
   * 获取用户
   * 
   * @param id 用户ID
   * @returns 用户实体或undefined
   */
  private getUser(id: bigint): Users | undefined {
    return this.users.get(id);
  }

  /**
   * 保存用户
   * 
   * @param user 用户实体
   */
  private saveUser(user: Users): void {
    this.users.set(user.id, user);
  }

  /**
   * 线程安全的ID生成方法
   * 
   * 技术实现：
   * 1. 检查ID生成锁的状态，避免并发冲突
   * 2. 使用超时机制防止死锁情况
   * 3. 获取锁后安全地递增ID计数器
   * 4. 确保锁在任何情况下都会被正确释放
   * 5. 返回新生成的唯一ID
   * 
   * @returns 新的唯一ID，保证全局唯一性
   * @throws Error 当ID生成超时或发生死锁时
   * 
   * @example
   * ```typescript
   * const newId = await this.generateId();
   * console.log(`生成新ID: ${newId}`);
   * ```
   */
  private async generateId(): Promise<bigint> {
    const lockKey = DATABASE_CONSTANTS.ID_GENERATION_LOCK_KEY;
    const maxWaitTime = SYSTEM_CONFIG.ID_GENERATION_TIMEOUT;
    const startTime = Date.now();
    
    // 改进的锁机制，添加超时保护
    while (this.ID_LOCK.has(lockKey)) {
      if (Date.now() - startTime > maxWaitTime) {
        throw new Error(ERROR_MESSAGES.ID_GENERATION_TIMEOUT);
      }
      // 使用 Promise 避免忙等待
      await new Promise(resolve => setTimeout(resolve, SYSTEM_CONFIG.LOCK_WAIT_INTERVAL));
    }
    
    this.ID_LOCK.add(lockKey);
    
    try {
      const newId = this.CURRENT_ID++;
      return newId;
    } finally {
      // 确保锁一定会被释放
      this.ID_LOCK.delete(lockKey);
    }
  }

  /**
   * 创建新用户
   * 
   * 技术实现：
   * 1. 验证输入数据的格式和完整性
   * 2. 检查用户名、邮箱、手机号、GitHub ID的唯一性
   * 3. 创建用户实体并分配唯一ID
   * 4. 设置默认值和时间戳
   * 5. 保存到内存存储并记录操作日志
   * 
   * @param createUserDto 创建用户的数据传输对象，包含用户基本信息
   * @returns 创建成功的用户实体，不包含敏感信息
   * @throws ConflictException 当用户名、邮箱、手机号或GitHub ID已存在时
   * @throws BadRequestException 当数据验证失败时
   * 
   * @example
   * const newUser = await userService.create({
   *   username: 'testuser',
   *   email: 'test@example.com',
   *   nickname: '测试用户'
   * });
   */
  async create(createUserDto: CreateUserDto): Promise<Users> {
    const monitor = PerformanceMonitor.create();
    this.logStart('创建用户', { username: createUserDto.username });

    try {
      // 验证DTO
      await this.validateUserDto(createUserDto);

      // 检查唯一性约束
      await this.checkUniquenessConstraints(createUserDto);

      // 创建用户实体
      const user = await this.createUserEntity(createUserDto);

      // 保存到内存
      this.saveUser(user);
      
      this.logSuccess('创建用户', { 
        userId: user.id.toString(), 
        username: user.username 
      }, monitor.getDuration());
      
      return user;
    } catch (error) {
      this.handleServiceError(error, '创建用户', {
        username: createUserDto.username,
        duration: monitor.getDuration()
      });
    }
  }

  /**
   * 验证用户DTO数据
   * 
   * @param createUserDto 用户数据
   * @throws BadRequestException 当数据验证失败时
   */
  private async validateUserDto(createUserDto: CreateUserDto): Promise<void> {
    const dto = plainToClass(CreateUserDto, createUserDto);
    const validationErrors = await validate(dto);
    
    if (validationErrors.length > 0) {
      const errorMessages = ValidationUtils.formatValidationErrors(validationErrors);
      throw new BadRequestException(`数据验证失败: ${errorMessages}`);
    }
  }

  /**
   * 检查唯一性约束
   * 
   * @param createUserDto 用户数据
   * @throws ConflictException 当发现重复数据时
   */
  private async checkUniquenessConstraints(createUserDto: CreateUserDto): Promise<void> {
    // 检查用户名是否已存在
    if (createUserDto.username) {
      const existingUser = await this.findByUsername(createUserDto.username);
      if (existingUser) {
        throw new ConflictException(ERROR_MESSAGES.USERNAME_EXISTS);
      }
    }

    // 检查邮箱是否已存在
    if (createUserDto.email) {
      const existingEmail = await this.findByEmail(createUserDto.email);
      if (existingEmail) {
        throw new ConflictException(ERROR_MESSAGES.EMAIL_EXISTS);
      }
    }

    // 检查手机号是否已存在
    if (createUserDto.phone) {
      const existingPhone = this.findUserByCondition(
        u => u.phone === createUserDto.phone
      );
      if (existingPhone) {
        throw new ConflictException(ERROR_MESSAGES.PHONE_EXISTS);
      }
    }

    // 检查GitHub ID是否已存在
    if (createUserDto.github_id) {
      const existingGithub = await this.findByGithubId(createUserDto.github_id);
      if (existingGithub) {
        throw new ConflictException(ERROR_MESSAGES.GITHUB_ID_EXISTS);
      }
    }
  }

  /**
   * 创建用户实体
   * 
   * @param createUserDto 用户数据
   * @returns 创建的用户实体
   */
  private async createUserEntity(createUserDto: CreateUserDto): Promise<Users> {
    const user = new Users();
    user.id = await this.generateId();
    user.username = createUserDto.username;
    user.email = createUserDto.email || null;
    user.phone = createUserDto.phone || null;
    user.password_hash = createUserDto.password_hash || null;
    user.nickname = createUserDto.nickname;
    user.github_id = createUserDto.github_id || null;
    user.avatar_url = createUserDto.avatar_url || null;
    user.role = createUserDto.role || USER_ROLES.NORMAL_USER;
    user.email_verified = createUserDto.email_verified || false;
    user.status = createUserDto.status || UserStatus.ACTIVE;
    user.created_at = new Date();
    user.updated_at = new Date();
    
    return user;
  }

  /**
   * 查询所有用户
   * 
   * 业务逻辑：
   * 1. 获取内存中的所有用户数据
   * 2. 按创建时间倒序排列（最新的在前）
   * 3. 应用分页参数进行数据切片
   * 4. 记录查询操作和性能指标
   * 
   * @param limit 限制返回数量，默认100，用于分页控制
   * @param offset 偏移量，默认0，用于分页控制
   * @returns 用户列表，按创建时间倒序排列
   * 
   * @example
   * // 获取前10个用户
   * const users = await userService.findAll(10, 0);
   * 
   * // 获取第二页用户（每页20个）
   * const secondPageUsers = await userService.findAll(20, 20);
   */
  async findAll(limit: number = QUERY_LIMITS.DEFAULT_LIMIT, offset: number = 0, includeDeleted: boolean = false): Promise<Users[]> {
    const monitor = PerformanceMonitor.create();
    this.logStart('查询所有用户', { limit, offset, includeDeleted });

    try {
      let allUsers = Array.from(this.users.values());
      
      // 注意：软删除功能暂未实现，includeDeleted参数预留用于未来扩展
      
      // 按创建时间倒序排列
      allUsers.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());
      
      const result = allUsers.slice(offset, offset + limit);
      
      this.logSuccess('查询所有用户', {
        resultCount: result.length,
        totalCount: allUsers.length,
        includeDeleted
      }, monitor.getDuration());
      
      return result;
    } catch (error) {
      this.handleServiceError(error, '查询所有用户', { 
        limit, 
        offset, 
        includeDeleted, 
        duration: monitor.getDuration() 
      });
    }
  }

  /**
   * 根据ID查询用户
   * 
   * 业务逻辑：
   * 1. 从内存Map中根据ID快速查找用户
   * 2. 验证用户是否存在
   * 3. 记录查询操作和结果
   * 4. 如果用户不存在则抛出404异常
   * 
   * @param id 用户ID，必须是有效的bigint类型
   * @returns 用户实体，包含完整的用户信息
   * @throws NotFoundException 当指定ID的用户不存在时
   * 
   * @example
   * try {
   *   const user = await userService.findOne(BigInt(123));
   *   console.log(user.username);
   * } catch (error) {
   *   // 处理用户不存在的情况
   * }
   */
  async findOne(id: bigint, includeDeleted: boolean = false): Promise<Users> {
    const monitor = PerformanceMonitor.create();
    this.logStart('查询用户', { userId: id.toString(), includeDeleted });

    try {
      const user = this.getUser(id);

      if (!user) {
        throw new NotFoundException(`ID为 ${id} 的用户不存在`);
      }

      this.logSuccess('查询用户', { 
        userId: id.toString(), 
        username: user.username,
        includeDeleted
      }, monitor.getDuration());
      
      return user;
    } catch (error) {
      this.handleServiceError(error, '查询用户', { 
        userId: id.toString(), 
        includeDeleted, 
        duration: monitor.getDuration() 
      });
    }
  }

  /**
   * 根据用户名查询用户
   * 
   * @param username 用户名
   * @param includeDeleted 是否包含已删除用户，默认false
   * @returns 用户实体或null
   */
  async findByUsername(username: string, includeDeleted: boolean = false): Promise<Users | null> {
    return this.findUserByCondition(u => u.username === username);
  }

  /**
   * 根据邮箱查询用户
   * 
   * @param email 邮箱
   * @param includeDeleted 是否包含已删除用户，默认false
   * @returns 用户实体或null
   */
  async findByEmail(email: string, includeDeleted: boolean = false): Promise<Users | null> {
    return this.findUserByCondition(u => u.email === email);
  }

  /**
   * 根据GitHub ID查询用户
   * 
   * @param githubId GitHub ID
   * @param includeDeleted 是否包含已删除用户，默认false
   * @returns 用户实体或null
   */
  async findByGithubId(githubId: string, includeDeleted: boolean = false): Promise<Users | null> {
    return this.findUserByCondition(u => u.github_id === githubId);
  }

  /**
   * 检查更新数据的唯一性约束
   * 
   * @param id 用户ID
   * @param updateData 更新数据
   * @param existingUser 现有用户
   * @throws ConflictException 当发现冲突时
   */
  private async checkUpdateUniquenessConstraints(
    id: bigint, 
    updateData: Partial<CreateUserDto>, 
    existingUser: Users
  ): Promise<void> {
    if (updateData.username && updateData.username !== existingUser.username) {
      const usernameExists = await this.findByUsername(updateData.username);
      if (usernameExists) {
        throw new ConflictException(ERROR_MESSAGES.USERNAME_EXISTS);
      }
    }

    if (updateData.email && updateData.email !== existingUser.email) {
      const emailExists = await this.findByEmail(updateData.email);
      if (emailExists) {
        throw new ConflictException(ERROR_MESSAGES.EMAIL_EXISTS);
      }
    }

    if (updateData.phone && updateData.phone !== existingUser.phone) {
      const phoneExists = this.findUserByCondition(
        u => u.phone === updateData.phone && u.id !== id
      );
      if (phoneExists) {
        throw new ConflictException(ERROR_MESSAGES.PHONE_EXISTS);
      }
    }

    if (updateData.github_id && updateData.github_id !== existingUser.github_id) {
      const githubExists = await this.findByGithubId(updateData.github_id);
      if (githubExists && githubExists.id !== id) {
        throw new ConflictException(ERROR_MESSAGES.GITHUB_ID_EXISTS);
      }
    }
  }

  /**
   * 更新用户信息
   * 
   * 业务逻辑：
   * 1. 验证目标用户是否存在
   * 2. 检查更新数据的唯一性约束（用户名、邮箱、手机号、GitHub ID）
   * 3. 应用更新数据到现有用户实体
   * 4. 更新时间戳并保存到内存
   * 5. 记录更新操作和性能指标
   * 
   * @param id 用户ID，必须是有效的bigint类型
   * @param updateData 更新的数据，可以是部分用户信息
   * @returns 更新后的用户实体，包含最新的信息和时间戳
   * @throws NotFoundException 当指定ID的用户不存在时
   * @throws ConflictException 当更新的数据与其他用户产生唯一性冲突时
   * 
   * @example
   * const updatedUser = await userService.update(BigInt(123), {
   *   nickname: '新昵称',
   *   email: 'newemail@example.com'
   * });
   */
  async update(id: bigint, updateData: Partial<CreateUserDto>): Promise<Users> {
    const monitor = PerformanceMonitor.create();
    this.logStart('更新用户', { 
      userId: id.toString(), 
      updateFields: Object.keys(updateData) 
    });

    try {
      // 检查用户是否存在
      const existingUser = await this.findOne(id);

      // 检查更新数据的唯一性约束
      await this.checkUpdateUniquenessConstraints(id, updateData, existingUser);

      // 更新用户数据
      Object.assign(existingUser, updateData);
      existingUser.updated_at = new Date();
      
      this.saveUser(existingUser);
      
      this.logSuccess('更新用户', { 
        userId: id.toString(), 
        username: existingUser.username 
      }, monitor.getDuration());
      
      return existingUser;
    } catch (error) {
      this.handleServiceError(error, '更新用户', { 
        userId: id.toString(), 
        duration: monitor.getDuration() 
      });
    }
  }

  /**
   * 删除用户
   * 
   * 业务逻辑：
   * 1. 验证目标用户是否存在
   * 2. 从内存Map中删除用户记录
   * 3. 记录删除操作和结果
   * 4. 返回删除操作的统计信息
   * 
   * @param id 用户ID，必须是有效的bigint类型
   * @returns 删除操作结果，包含影响的记录数和操作消息
   * @throws NotFoundException 当指定ID的用户不存在时
   * 
   * @example
   * const result = await userService.remove(BigInt(123));
   * console.log(result.message); // "成功删除ID为 123 的用户"
   */
  async remove(id: bigint): Promise<{ affected: number; message: string }> {
    const monitor = PerformanceMonitor.create();
    this.logStart('删除用户', { userId: id.toString() });

    try {
      // 检查用户是否存在
      const user = await this.findOne(id);

      // 执行删除
      const deleted = this.users.delete(id);

      const result = {
        affected: deleted ? 1 : 0,
        message: `成功删除ID为 ${id} 的用户`
      };

      this.logSuccess('删除用户', { 
        userId: id.toString(), 
        username: user.username 
      }, monitor.getDuration());
      
      return result;
    } catch (error) {
      this.handleServiceError(error, '删除用户', { 
        userId: id.toString(), 
        duration: monitor.getDuration() 
      });
    }
  }

  /**
   * 软删除用户（内存模式下设置删除时间）
   * 
   * @param id 用户ID
   * @returns 被软删除的用户实体
   */
  async softRemove(id: bigint): Promise<Users> {
    const user = await this.findOne(id);
    // 注意：软删除功能暂未实现，当前仅返回用户实体
    this.saveUser(user);
    return user;
  }

  /**
   * 统计用户数量
   * 
   * @param conditions 查询条件（内存模式下简化处理）
   * @returns 用户数量
   */
  async count(conditions?: Record<string, any>): Promise<number> {
    if (!conditions) {
      return this.users.size;
    }
    
    // 简化的条件过滤
    let count = 0;
    for (const user of this.users.values()) {
      let match = true;
      for (const [key, value] of Object.entries(conditions)) {
        if ((user as any)[key] !== value) {
          match = false;
          break;
        }
      }
      if (match) count++;
    }
    
    return count;
  }

  /**
   * 检查用户是否存在
   * 
   * @param id 用户ID
   * @returns 是否存在
   */
  async exists(id: bigint): Promise<boolean> {
    return this.users.has(id);
  }

  /**
   * 创建新用户（带重复检查）
   * 
   * 业务逻辑：
   * 1. 检查用户名、邮箱、手机号、GitHub ID的唯一性
   * 2. 如果所有检查都通过，调用create方法创建用户
   * 3. 记录操作日志和性能指标
   * 
   * @param createUserDto 创建用户的数据传输对象
   * @returns 创建的用户实体
   * @throws ConflictException 当用户名、邮箱、手机号或GitHub ID已存在时
   * @throws BadRequestException 当数据验证失败时
   */
  async createWithDuplicateCheck(createUserDto: CreateUserDto): Promise<Users> {
    const monitor = PerformanceMonitor.create();
    
    this.logStart('创建用户（带重复检查）', {
      username: createUserDto.username,
      email: createUserDto.email,
      phone: createUserDto.phone,
      github_id: createUserDto.github_id
    });

    try {
      // 执行所有唯一性检查
      await this.checkUniquenessConstraints(createUserDto);

      // 调用普通的创建方法
      const user = await this.create(createUserDto);
      
      this.logSuccess('创建用户（带重复检查）', {
        userId: user.id.toString(),
        username: user.username
      }, monitor.getDuration());

      return user;
    } catch (error) {
      this.handleServiceError(error, '创建用户（带重复检查）', {
        username: createUserDto.username,
        duration: monitor.getDuration()
      });
    }
  }

  /**
   * 批量创建用户
   * 
   * 业务逻辑：
   * 1. 遍历用户数据数组
   * 2. 对每个用户数据调用create方法
   * 3. 收集所有创建成功的用户
   * 4. 记录批量操作的统计信息和性能指标
   * 5. 如果某个用户创建失败，整个操作会中断并抛出异常
   * 
   * @param createUserDtos 用户数据数组，每个元素都是CreateUserDto类型
   * @returns 创建成功的用户列表，顺序与输入数组一致
   * @throws ConflictException 当任何用户的唯一性约束冲突时
   * @throws BadRequestException 当任何用户的数据验证失败时
   * 
   * @example
   * const users = await userService.createBatch([
   *   { username: 'user1', email: 'user1@example.com', nickname: '用户1' },
   *   { username: 'user2', email: 'user2@example.com', nickname: '用户2' }
   * ]);
   */
  async createBatch(createUserDtos: CreateUserDto[]): Promise<Users[]> {
    const monitor = PerformanceMonitor.create();
    this.logStart('批量创建用户', { count: createUserDtos.length });

    try {
      const users: Users[] = [];
      const createdUsers: Users[] = []; // 用于回滚的记录

      try {
        for (const dto of createUserDtos) {
          const user = await this.create(dto);
          users.push(user);
          createdUsers.push(user);
        }

        this.logSuccess('批量创建用户', { 
          createdCount: users.length 
        }, monitor.getDuration());

        return users;
      } catch (error) {
        // 回滚已创建的用户
        for (const user of createdUsers) {
          this.users.delete(user.id);
        }
        throw error;
      }
    } catch (error) {
      this.handleServiceError(error, '批量创建用户', { 
        count: createUserDtos.length, 
        duration: monitor.getDuration() 
      });
    }
  }

  /**
   * 根据角色查询用户
   * 
   * @param role 角色值
   * @param includeDeleted 是否包含已删除用户，默认false
   * @returns 用户列表
   */
  async findByRole(role: number, includeDeleted: boolean = false): Promise<Users[]> {
    return Array.from(this.users.values())
      .filter(u => u.role === role)
      .sort((a, b) => b.created_at.getTime() - a.created_at.getTime());
  }

  /**
   * 搜索用户（根据用户名或昵称）
   * 
   * 业务逻辑：
   * 1. 将搜索关键词转换为小写以实现大小写不敏感搜索
   * 2. 遍历所有用户，匹配用户名或昵称中包含关键词的用户
   * 3. 按创建时间倒序排列搜索结果
   * 4. 限制返回结果数量以提高性能
   * 5. 记录搜索操作和性能指标
   * 
   * @param keyword 搜索关键词，支持部分匹配，大小写不敏感
   * @param limit 限制返回数量，默认20，防止结果过多影响性能
   * @returns 匹配的用户列表，按创建时间倒序排列
   * 
   * @example
   * // 搜索用户名或昵称包含"admin"的用户
   * const users = await userService.search('admin', 10);
   * 
   * // 搜索所有包含"测试"的用户
   * const testUsers = await userService.search('测试');
   */
  async search(keyword: string, limit: number = QUERY_LIMITS.DEFAULT_SEARCH_LIMIT, includeDeleted: boolean = false): Promise<Users[]> {
    const monitor = PerformanceMonitor.create();
    this.logStart('搜索用户', { keyword, limit, includeDeleted });

    try {
      const lowerKeyword = keyword.toLowerCase();
      
      const results = Array.from(this.users.values())
        .filter(u => {
          // 注意：软删除功能暂未实现，includeDeleted参数预留用于未来扩展
          
          // 检查关键词匹配
          return u.username.toLowerCase().includes(lowerKeyword) ||
                 u.nickname.toLowerCase().includes(lowerKeyword);
        })
        .sort((a, b) => b.created_at.getTime() - a.created_at.getTime())
        .slice(0, limit);

      this.logSuccess('搜索用户', { 
        keyword, 
        resultCount: results.length,
        includeDeleted
      }, monitor.getDuration());
      
      return results;
    } catch (error) {
      // 搜索异常使用特殊处理，返回空数组而不抛出异常
      return this.handleSearchError(error, '搜索用户', { 
        keyword, 
        limit, 
        includeDeleted, 
        duration: monitor.getDuration() 
      });
    }
  }
}
