/**
 * 用户档案基础服务类
 * 
 * 功能描述：
 * - 提供用户档案服务的基础功能和通用方法
 * - 定义日志记录和性能监控的标准模式
 * - 实现错误处理和异常管理的统一规范
 * - 支持双模式运行的基础架构
 * 
 * 职责分离：
 * - 日志管理：统一的日志记录格式和级别
 * - 性能监控：操作耗时统计和性能指标
 * - 错误处理：标准化的异常处理模式
 * - 工具方法：通用的辅助功能和验证逻辑
 * 
 * 继承关系：
 * - UserProfilesService extends BaseUserProfilesService (MySQL实现)
 * - UserProfilesMemoryService extends BaseUserProfilesService (内存实现)
 * 
 * 最近修改：
 * - 2026-01-08: 功能新增 - 创建用户档案基础服务类 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.0.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { Logger } from '@nestjs/common';

/**
 * 用户档案基础服务抽象类
 * 
 * 职责：
 * - 提供所有用户档案服务的通用基础功能
 * - 定义标准的日志记录和性能监控模式
 * - 实现统一的错误处理和异常管理
 * - 支持MySQL和内存两种存储模式
 * 
 * 设计模式：
 * - 模板方法模式：定义通用的操作流程
 * - 策略模式：支持不同的存储实现策略
 * - 观察者模式：统一的日志和监控机制
 * 
 * 使用场景：
 * - 作为具体用户档案服务的基类
 * - 提供标准化的日志和监控功能
 * - 实现通用的工具方法和验证逻辑
 */
export abstract class BaseUserProfilesService {
  /**
   * 日志记录器
   * 
   * 功能：
   * - 记录用户档案操作的详细日志
   * - 支持不同级别的日志输出
   * - 提供结构化的日志格式
   * - 便于问题排查和性能分析
   */
  protected readonly logger = new Logger(BaseUserProfilesService.name);

  /**
   * 记录操作开始日志
   * 
   * 功能描述：
   * 统一记录操作开始的日志信息，包含操作类型、参数和时间戳
   * 
   * @param operation 操作名称
   * @param params 操作参数
   * 
   * @example
   * ```typescript
   * this.logStart('创建用户档案', { 
   *   userId: '123', 
   *   currentMap: 'plaza' 
   * });
   * ```
   */
  protected logStart(operation: string, params: Record<string, any>): void {
    this.logger.log(`开始${operation}`, {
      operation: this.formatOperationName(operation),
      ...params,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 记录操作成功日志
   * 
   * 功能描述：
   * 统一记录操作成功的日志信息，包含结果数据和性能指标
   * 
   * @param operation 操作名称
   * @param result 操作结果
   * @param duration 操作耗时（毫秒）
   * 
   * @example
   * ```typescript
   * this.logSuccess('创建用户档案', { 
   *   profileId: '456' 
   * }, 150);
   * ```
   */
  protected logSuccess(operation: string, result: Record<string, any>, duration: number): void {
    this.logger.log(`${operation}成功`, {
      operation: this.formatOperationName(operation),
      ...result,
      duration,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 记录操作警告日志
   * 
   * 功能描述：
   * 统一记录操作警告的日志信息，用于记录非致命性问题
   * 
   * @param operation 操作名称
   * @param warning 警告信息
   * @param params 相关参数
   * 
   * @example
   * ```typescript
   * this.logWarning('更新用户位置', '用户档案不存在', { 
   *   userId: '123' 
   * });
   * ```
   */
  protected logWarning(operation: string, warning: string, params: Record<string, any>): void {
    this.logger.warn(`${operation}警告：${warning}`, {
      operation: this.formatOperationName(operation),
      warning,
      ...params,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 记录操作错误日志
   * 
   * 功能描述：
   * 统一记录操作错误的日志信息，包含错误详情和堆栈信息
   * 
   * @param operation 操作名称
   * @param error 错误信息
   * @param params 相关参数
   * @param duration 操作耗时（毫秒）
   * @param stack 错误堆栈（可选）
   * 
   * @example
   * ```typescript
   * this.logError('创建用户档案', '数据库连接失败', { 
   *   userId: '123' 
   * }, 500, error.stack);
   * ```
   */
  protected logError(
    operation: string, 
    error: string, 
    params: Record<string, any>, 
    duration: number, 
    stack?: string
  ): void {
    this.logger.error(`${operation}失败：${error}`, {
      operation: this.formatOperationName(operation),
      error,
      ...params,
      duration,
      timestamp: new Date().toISOString()
    }, stack);
  }

  /**
   * 处理搜索异常
   * 
   * 功能描述：
   * 专门处理搜索操作的异常，返回空结果而不抛出异常
   * 
   * 设计理念：
   * - 搜索失败不应该影响用户体验
   * - 返回空结果比抛出异常更友好
   * - 记录错误日志便于问题排查
   * 
   * @param error 异常对象
   * @param operation 操作名称
   * @param params 操作参数
   * @returns 空数组
   * 
   * @example
   * ```typescript
   * try {
   *   return await this.searchProfiles(keyword);
   * } catch (error) {
   *   return this.handleSearchError(error, '搜索用户档案', { keyword });
   * }
   * ```
   */
  protected handleSearchError<T>(
    error: any, 
    operation: string, 
    params: Record<string, any>
  ): T[] {
    this.logError(
      operation,
      error instanceof Error ? error.message : String(error),
      params,
      0, // 搜索异常不计算耗时
      error instanceof Error ? error.stack : undefined
    );
    
    // 搜索异常返回空数组，不影响用户体验
    return [];
  }

  /**
   * 格式化操作名称
   * 
   * 功能描述：
   * 将中文操作名称转换为英文标识符，便于日志分析和监控
   * 
   * @param operation 中文操作名称
   * @returns 英文操作标识符
   * 
   * @example
   * ```typescript
   * this.formatOperationName('创建用户档案'); // 返回: 'createUserProfile'
   * this.formatOperationName('更新用户位置'); // 返回: 'updateUserPosition'
   * ```
   */
  private formatOperationName(operation: string): string {
    const operationMap: Record<string, string> = {
      '创建用户档案': 'createUserProfile',
      '查询用户档案': 'findUserProfile',
      '更新用户档案': 'updateUserProfile',
      '更新用户位置': 'updateUserPosition',
      '删除用户档案': 'removeUserProfile',
      '搜索用户档案': 'searchUserProfiles',
      '查询地图用户': 'findUsersByMap',
      '批量更新状态': 'batchUpdateStatus',
      '统计用户数量': 'countUserProfiles'
    };

    return operationMap[operation] || operation.toLowerCase().replace(/\s+/g, '_');
  }

  /**
   * 验证用户ID格式
   * 
   * 功能描述：
   * 验证用户ID是否为有效的bigint格式
   * 
   * @param userId 用户ID
   * @returns 是否有效
   * 
   * @example
   * ```typescript
   * if (!this.isValidUserId(userId)) {
   *   throw new BadRequestException('用户ID格式无效');
   * }
   * ```
   */
  protected isValidUserId(userId: any): userId is bigint {
    try {
      const id = BigInt(userId);
      return id > 0;
    } catch {
      return false;
    }
  }

  /**
   * 验证坐标格式
   * 
   * 功能描述：
   * 验证位置坐标是否为有效的数字格式
   * 
   * @param coordinate 坐标值
   * @returns 是否有效
   * 
   * @example
   * ```typescript
   * if (!this.isValidCoordinate(posX) || !this.isValidCoordinate(posY)) {
   *   throw new BadRequestException('坐标格式无效');
   * }
   * ```
   */
  protected isValidCoordinate(coordinate: any): coordinate is number {
    return typeof coordinate === 'number' && 
           !isNaN(coordinate) && 
           isFinite(coordinate);
  }

  /**
   * 验证地图名称格式
   * 
   * 功能描述：
   * 验证地图名称是否符合规范要求
   * 
   * @param mapName 地图名称
   * @returns 是否有效
   * 
   * @example
   * ```typescript
   * if (!this.isValidMapName(currentMap)) {
   *   throw new BadRequestException('地图名称格式无效');
   * }
   * ```
   */
  protected isValidMapName(mapName: any): mapName is string {
    return typeof mapName === 'string' && 
           mapName.length > 0 && 
           mapName.length <= 50 &&
           /^[a-zA-Z0-9_-]+$/.test(mapName); // 只允许字母、数字、下划线、连字符
  }

  /**
   * 清理敏感数据
   * 
   * 功能描述：
   * 从日志数据中移除敏感信息，保护用户隐私
   * 
   * @param data 原始数据
   * @returns 清理后的数据
   * 
   * @example
   * ```typescript
   * const safeData = this.sanitizeLogData({
   *   userId: '123',
   *   email: 'user@example.com',
   *   password: 'secret123'
   * });
   * // 返回: { userId: '123', email: 'u***@example.com', password: '***' }
   * ```
   */
  protected sanitizeLogData(data: Record<string, any>): Record<string, any> {
    const sensitiveFields = ['password', 'token', 'secret', 'key'];
    const emailFields = ['email'];
    
    const sanitized = { ...data };
    
    for (const [key, value] of Object.entries(sanitized)) {
      const lowerKey = key.toLowerCase();
      
      // 完全隐藏敏感字段
      if (sensitiveFields.some(field => lowerKey.includes(field))) {
        sanitized[key] = '***';
      }
      // 部分隐藏邮箱字段
      else if (emailFields.some(field => lowerKey.includes(field)) && typeof value === 'string') {
        sanitized[key] = this.maskEmail(value);
      }
    }
    
    return sanitized;
  }

  /**
   * 邮箱脱敏处理
   * 
   * 功能描述：
   * 对邮箱地址进行脱敏处理，保护用户隐私
   * 
   * @param email 邮箱地址
   * @returns 脱敏后的邮箱
   * 
   * @example
   * ```typescript
   * this.maskEmail('user@example.com'); // 返回: 'u***@example.com'
   * this.maskEmail('longusername@test.org'); // 返回: 'l***@test.org'
   * ```
   */
  private maskEmail(email: string): string {
    if (!email || !email.includes('@')) {
      return '***';
    }
    
    const [username, domain] = email.split('@');
    if (username.length <= 1) {
      return `***@${domain}`;
    }
    
    return `${username[0]}***@${domain}`;
  }

  /**
   * 计算操作耗时
   * 
   * 功能描述：
   * 计算操作的执行时间，用于性能监控
   * 
   * @param startTime 开始时间戳
   * @returns 耗时（毫秒）
   * 
   * @example
   * ```typescript
   * const startTime = Date.now();
   * // ... 执行操作
   * const duration = this.calculateDuration(startTime);
   * this.logSuccess('操作完成', { result }, duration);
   * ```
   */
  protected calculateDuration(startTime: number): number {
    return Date.now() - startTime;
  }

  /**
   * 生成操作ID
   * 
   * 功能描述：
   * 生成唯一的操作ID，用于跟踪和关联日志
   * 
   * @returns 操作ID
   * 
   * @example
   * ```typescript
   * const operationId = this.generateOperationId();
   * this.logger.log('开始操作', { operationId, ...params });
   * ```
   */
  protected generateOperationId(): string {
    return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
  }
}