/**
 * 管理员模块工具函数
 * 
 * 功能描述：
 * - 提供管理员模块通用的工具函数
 * - 消除重复代码，提高代码复用性
 * - 统一处理常见的业务逻辑
 * 
 * 职责分离：
 * - 工具函数集中管理
 * - 重复逻辑抽象
 * - 通用功能封装
 * 
 * 最近修改：
 * - 2026-01-08: 重构 - 文件夹扁平化，移动到上级目录并更新import路径 (修改者: moyin)
 * - 2026-01-08: 代码质量优化 - 提取魔法数字为常量，添加用户格式化工具和操作监控工具 (修改者: moyin)
 * - 2026-01-08: 功能新增 - 创建管理员模块工具函数 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.3.0
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { PAGINATION_LIMITS, REQUEST_ID_PREFIXES, SENSITIVE_FIELDS } from './admin_constants';

/**
 * 请求ID生成常量
 */
const REQUEST_ID_RANDOM_LENGTH = 9; // 随机字符串长度
const REQUEST_ID_RANDOM_START = 2;  // 跳过'0.'前缀

/**
 * 安全限制查询数量
 * 
 * @param limit 请求的限制数量
 * @param maxLimit 最大允许的限制数量
 * @returns 安全的限制数量
 */
export function safeLimitValue(limit: number, maxLimit: number): number {
  return Math.min(Math.max(limit, 1), maxLimit);
}

/**
 * 安全限制偏移量
 * 
 * @param offset 请求的偏移量
 * @returns 安全的偏移量（不小于0）
 */
export function safeOffsetValue(offset: number): number {
  return Math.max(offset, PAGINATION_LIMITS.DEFAULT_OFFSET);
}

/**
 * 生成唯一的请求ID
 * 
 * @param prefix 请求ID前缀
 * @returns 唯一的请求ID
 */
export function generateRequestId(prefix: string = REQUEST_ID_PREFIXES.GENERAL): string {
  return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(REQUEST_ID_RANDOM_START, REQUEST_ID_RANDOM_START + REQUEST_ID_RANDOM_LENGTH)}`;
}

/**
 * 获取当前时间戳字符串
 * 
 * @returns ISO格式的时间戳字符串
 */
export function getCurrentTimestamp(): string {
  return new Date().toISOString();
}

/**
 * 清理请求体中的敏感信息
 * 
 * @param body 请求体对象
 * @returns 清理后的请求体
 */
export function sanitizeRequestBody(body: any): any {
  if (!body || typeof body !== 'object') {
    return body;
  }

  const sanitized = { ...body };

  for (const field of SENSITIVE_FIELDS) {
    if (sanitized[field]) {
      sanitized[field] = '***REDACTED***';
    }
  }

  return sanitized;
}

/**
 * 提取客户端IP地址
 * 
 * @param request 请求对象
 * @returns 客户端IP地址
 */
export function extractClientIp(request: any): string {
  return request.ip || 
         request.connection?.remoteAddress || 
         request.socket?.remoteAddress ||
         (request.connection?.socket as any)?.remoteAddress ||
         request.headers['x-forwarded-for']?.split(',')[0] ||
         request.headers['x-real-ip'] ||
         'unknown';
}

/**
 * 创建标准的成功响应
 * 
 * @param data 响应数据
 * @param message 响应消息
 * @param requestIdPrefix 请求ID前缀
 * @returns 标准格式的成功响应
 */
export function createSuccessResponse<T>(
  data: T, 
  message: string, 
  requestIdPrefix?: string
): {
  success: true;
  data: T;
  message: string;
  timestamp: string;
  request_id: string;
} {
  return {
    success: true,
    data,
    message,
    timestamp: getCurrentTimestamp(),
    request_id: generateRequestId(requestIdPrefix)
  };
}

/**
 * 创建标准的错误响应
 * 
 * @param message 错误消息
 * @param errorCode 错误码
 * @param requestIdPrefix 请求ID前缀
 * @returns 标准格式的错误响应
 */
export function createErrorResponse(
  message: string, 
  errorCode?: string,
  requestIdPrefix?: string
): {
  success: false;
  message: string;
  error_code?: string;
  timestamp: string;
  request_id: string;
} {
  return {
    success: false,
    message,
    error_code: errorCode,
    timestamp: getCurrentTimestamp(),
    request_id: generateRequestId(requestIdPrefix)
  };
}

/**
 * 创建标准的列表响应
 * 
 * @param items 列表项
 * @param total 总数
 * @param limit 限制数量
 * @param offset 偏移量
 * @param message 响应消息
 * @param requestIdPrefix 请求ID前缀
 * @returns 标准格式的列表响应
 */
export function createListResponse<T>(
  items: T[], 
  total: number, 
  limit: number, 
  offset: number, 
  message: string,
  requestIdPrefix?: string
): {
  success: true;
  data: {
    items: T[];
    total: number;
    limit: number;
    offset: number;
    has_more: boolean;
  };
  message: string;
  timestamp: string;
  request_id: string;
} {
  return {
    success: true,
    data: {
      items,
      total,
      limit,
      offset,
      has_more: offset + items.length < total
    },
    message,
    timestamp: getCurrentTimestamp(),
    request_id: generateRequestId(requestIdPrefix)
  };
}

/**
 * 限制保留天数在合理范围内
 * 
 * @param daysToKeep 请求的保留天数
 * @param minDays 最少保留天数
 * @param maxDays 最多保留天数
 * @returns 安全的保留天数
 */
export function safeDaysToKeep(daysToKeep: number, minDays: number, maxDays: number): number {
  return Math.max(minDays, Math.min(daysToKeep, maxDays));
}

/**
 * 用户数据格式化工具
 */
export class UserFormatter {
  /**
   * 格式化用户基本信息
   * 
   * @param user 用户实体
   * @returns 格式化的用户信息
   */
  static formatBasicUser(user: any) {
    return {
      id: user.id.toString(),
      username: user.username,
      nickname: user.nickname,
      email: user.email,
      phone: user.phone,
      role: user.role,
      status: user.status,
      email_verified: user.email_verified,
      avatar_url: user.avatar_url,
      created_at: user.created_at,
      updated_at: user.updated_at
    };
  }

  /**
   * 格式化用户详细信息（包含GitHub ID）
   * 
   * @param user 用户实体
   * @returns 格式化的用户详细信息
   */
  static formatDetailedUser(user: any) {
    return {
      ...this.formatBasicUser(user),
      github_id: user.github_id
    };
  }
}

/**
 * 操作性能监控工具
 */
export class OperationMonitor {
  /**
   * 执行带性能监控的操作
   * 
   * @param operationName 操作名称
   * @param context 操作上下文
   * @param operation 要执行的操作
   * @param logger 日志记录器
   * @returns 操作结果
   */
  static async executeWithMonitoring<T>(
    operationName: string,
    context: Record<string, any>,
    operation: () => Promise<T>,
    logger: (level: 'log' | 'warn' | 'error', message: string, context: Record<string, any>) => void
  ): Promise<T> {
    const startTime = Date.now();
    
    logger('log', `开始${operationName}`, {
      operation: operationName,
      ...context
    });

    try {
      const result = await operation();
      
      const duration = Date.now() - startTime;
      
      logger('log', `${operationName}成功`, {
        operation: operationName,
        duration,
        ...context
      });

      return result;
    } catch (error) {
      const duration = Date.now() - startTime;
      
      logger('error', `${operationName}失败`, {
        operation: operationName,
        duration,
        error: error instanceof Error ? error.message : String(error),
        ...context
      });

      throw error;
    }
  }
}