/**
 * 超时处理装饰器
 *
 * 功能描述：
 * - 为API接口添加超时控制
 * - 防止长时间运行的请求阻塞系统
 * - 提供友好的超时错误提示
 *
 * 职责分离：
 * - 超时装饰器定义和配置管理
 * - 预设超时配置常量的维护
 * - 超时元数据的设置和Swagger文档生成
 *
 * 使用场景：
 * - 数据库查询超时控制
 * - 外部API调用超时
 * - 文件上传下载超时
 * - 复杂计算任务超时
 *
 * 最近修改：
 * - 2026-01-07: 代码规范优化 - 更新注释规范，完善装饰器说明
 *
 * @author moyin
 * @version 1.0.1
 * @since 2025-12-24
 * @lastModified 2026-01-07
 */

import { SetMetadata, applyDecorators } from '@nestjs/common';
import { ApiResponse } from '@nestjs/swagger';

/**
 * 超时配置元数据键
 */
export const TIMEOUT_KEY = 'timeout';

/**
 * 超时配置接口
 */
export interface TimeoutConfig {
  /** 超时时间（毫秒） */
  timeout: number;
  /** 自定义超时错误消息 */
  message?: string;
  /** 是否记录超时日志 */
  logTimeout?: boolean;
}

/**
 * 超时装饰器
 *
 * 业务逻辑：
 * 1. 接收超时配置参数（数字或配置对象）
 * 2. 标准化超时配置格式
 * 3. 设置超时元数据到方法或类上
 * 4. 生成对应的Swagger API响应文档
 *
 * @param config 超时配置或超时时间（毫秒）
 * @returns 装饰器函数
 * @throws RequestTimeoutException 当请求执行时间超过设定值时
 *
 * @example
 * ```typescript
 * // 设置30秒超时
 * @Timeout(30000)
 * @Get('slow-operation')
 * async slowOperation() { ... }
 *
 * // 自定义超时配置
 * @Timeout({
 *   timeout: 60000,
 *   message: '数据查询超时，请稍后重试',
 *   logTimeout: true
 * })
 * @Post('complex-query')
 * async complexQuery() { ... }
 * ```
 */
export function Timeout(config: number | TimeoutConfig) {
  const timeoutConfig: TimeoutConfig = typeof config === 'number'
    ? { timeout: config }
    : config;

  return applyDecorators(
    SetMetadata(TIMEOUT_KEY, timeoutConfig),
    ApiResponse({
      status: 408,
      description: timeoutConfig.message || '请求超时',
      schema: {
        type: 'object',
        properties: {
          success: { type: 'boolean', example: false },
          message: { type: 'string', example: timeoutConfig.message || '请求超时，请稍后重试' },
          error_code: { type: 'string', example: 'REQUEST_TIMEOUT' },
          timeout_info: {
            type: 'object',
            properties: {
              timeout_ms: { type: 'number', example: timeoutConfig.timeout },
              timestamp: { type: 'string', example: '2025-12-24T10:00:00.000Z' }
            }
          }
        }
      }
    })
  );
}

/**
 * 预定义的超时配置
 */
export const TimeoutPresets = {
  /** 快速操作：5秒 */
  FAST: { timeout: 5000, message: '操作超时，请检查网络连接' },

  /** 一般操作：30秒 */
  NORMAL: { timeout: 30000, message: '请求超时，请稍后重试' },

  /** 慢操作：60秒 */
  SLOW: { timeout: 60000, message: '操作超时，请稍后重试' },

  /** 文件操作：2分钟 */
  FILE_OPERATION: { timeout: 120000, message: '文件操作超时，请检查文件大小和网络状况' },

  /** 数据库查询：45秒 */
  DATABASE_QUERY: { timeout: 45000, message: '数据查询超时，请简化查询条件或稍后重试' },

  /** 外部API调用：15秒 */
  EXTERNAL_API: { timeout: 15000, message: '外部服务调用超时，请稍后重试' },

  /** 邮件发送：30秒 */
  EMAIL_SEND: { timeout: 30000, message: '邮件发送超时，请检查邮件服务配置' },

  /** 长时间任务：5分钟 */
  LONG_TASK: { timeout: 300000, message: '任务执行超时，请稍后重试' }
} as const;