/**
 * 系统提示词构建器
 * 负责从多个来源组合系统提示词各部分
 * 支持插件注册自己的提示词部分，支持重载后更新
 */

class SystemPromptPart {
  constructor(name, priority, provider) {
    this.name = name;
    this.priority = priority;
    this._provider = provider;
    this._dirty = true;
    this._cached = null;
  }

  get() {
    if (this._dirty || this._cached === null) {
      try {
        this._cached = this._provider();
        this._dirty = false;
      } catch (e) {
        console.warn(`[SystemPromptPart:${this.name}] Provider failed:`, e.message);
        this._cached = null;
      }
    }
    return this._cached;
  }

  invalidate() {
    this._dirty = true;
  }
}

class SystemPromptBuilder {
  constructor() {
    this._parts = new Map(); // name -> SystemPromptPart
    this._orderedParts = []; // sorted by priority
  }

  /**
   * 注册一个提示词部分
   * @param {string} name - 部分名称（唯一标识）
   * @param {number} priority - 优先级（数字越小越靠前）
   * @param {Function} provider - 返回提示词内容的函数
   */
  register(name, priority, provider) {
    const part = new SystemPromptPart(name, priority, provider);
    this._parts.set(name, part);
    this._reorder();
    return this;
  }

  /**
   * 注销一个提示词部分
   */
  unregister(name) {
    this._parts.delete(name);
    this._reorder();
    return this;
  }

  /**
   * 使某个部分失效（下次 get 时会重新计算）
   */
  invalidate(name) {
    const part = this._parts.get(name);
    if (part) {
      part.invalidate();
    }
    return this;
  }

  /**
   * 使所有部分失效
   */
  invalidateAll() {
    for (const part of this._parts.values()) {
      part.invalidate();
    }
    return this;
  }

  /**
   * 获取某个部分的内容
   */
  getPart(name) {
    const part = this._parts.get(name);
    return part ? part.get() : null;
  }

  /**
   * 构建完整的系统提示词
   * @returns {string}
   */
  build() {
    const parts = [];
    for (const part of this._orderedParts) {
      const content = part.get();
      if (content && content.trim()) {
        parts.push(content.trim());
      }
    }
    return parts.join('\n\n');
  }

  /**
   * 获取所有部分名称
   */
  getPartNames() {
    return [...this._parts.keys()];
  }

  _reorder() {
    this._orderedParts = Array.from(this._parts.values()).sort(
      (a, b) => a.priority - b.priority
    );
  }
}

module.exports = { SystemPromptBuilder, SystemPromptPart };
