/**
 * RequestContext - Request 级别的上下文封装
 *
 * 职责：
 * 1. 追踪请求链路（requestId, traceId）
 * 2. 管理请求级超时
 * 3. 传递请求元数据
 */

const { uuid } = require('../utils/id');

class RequestContext {
  /**
   * @param {Object} options - 配置选项
   * @param {string} [options.requestId] - 请求 ID，默认自动生成
   * @param {string} [options.traceId] - 追踪 ID，默认自动生成
   * @param {string} [options.parentSpanId] - 父 span ID
   * @param {number} [options.timeout] - 超时时间（毫秒），默认 120000
   * @param {boolean} [options.isStream] - 是否为流式请求
   * @param {string} [options.userId] - 用户标识
   */
  constructor(options = {}) {
    this.requestId = options.requestId || `req_${uuid()}`;
    this.traceId = options.traceId || `trace_${uuid()}`;
    this.traceId = options.traceId || generateId();
    this.parentSpanId = options.parentSpanId || null;

    this.timeout = options.timeout || 120000; // 默认 2 分钟
    this.startTime = options.startTime || Date.now();

    this.isStream = options.isStream || false;
    this.userId = options.userId || null;

    // 请求级状态
    this.cancelled = false;
    this.abortController = null;

    // 元数据
    this.metadata = options.metadata || {};
  }

  /**
   * 创建 AbortController（延迟初始化）
   * @returns {AbortController}
   */
  getAbortController() {
    if (!this.abortController) {
      this.abortController = new AbortController();
    }
    return this.abortController;
  }

  /**
   * 检查是否超时
   * @returns {boolean}
   */
  isTimeout() {
    return Date.now() - this.startTime > this.timeout;
  }

  /**
   * 取消请求
   */
  cancel() {
    this.cancelled = true;
    if (this.abortController) {
      this.abortController.abort();
    }
  }

  /**
   * 获取请求耗时（毫秒）
   * @returns {number}
   */
  getElapsed() {
    return Date.now() - this.startTime;
  }

  /**
   * 获取请求摘要
   * @returns {Object}
   */
  toJSON() {
    return {
      requestId: this.requestId,
      traceId: this.traceId,
      parentSpanId: this.parentSpanId,
      timeout: this.timeout,
      startTime: this.startTime,
      elapsed: this.getElapsed(),
      isStream: this.isStream,
      userId: this.userId,
      cancelled: this.cancelled,
    };
  }
}

module.exports = { RequestContext };
