/**
 * SessionStorageAdapter - Session 持久化存储适配器
 *
 * 支持多种存储后端：
 * - Memory: 内存存储（默认）
 * - File: JSON 文件存储
 * - Future: Database, Redis 等
 */

const fs = require('fs');
const path = require('path');

class SessionStorageAdapter {
  /**
   * @param {Object} options - 配置选项
   * @param {string} [options.type='memory'] - 存储类型: 'memory', 'file'
   * @param {string} [options.baseDir='.agent/sessions'] - 文件存储基础目录
   */
  constructor(options = {}) {
    this.type = options.type || 'memory';
    this.baseDir = options.baseDir || '.agent/sessions';

    if (this.type === 'file') {
      this._ensureDirectory();
    }

    // 内存存储
    this._memoryStore = new Map();

    // 写回队列（用于 debounce）
    this._writeQueue = null;
    this._writeTimeout = null;
  }

  /**
   * 确保目录存在
   * @private
   */
  _ensureDirectory() {
    const dir = path.resolve(process.cwd(), this.baseDir);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
  }

  /**
   * 获取存储文件路径
   * @param {string} sessionId
   * @returns {string}
   * @private
   */
  _getFilePath(sessionId) {
    return path.resolve(process.cwd(), this.baseDir, `${sessionId}.json`);
  }

  /**
   * 保存 Session 数据
   * @param {string} sessionId - 会话 ID
   * @param {Object} data - 要保存的数据
   * @returns {Promise}
   */
  async save(sessionId, data) {
    if (this.type === 'memory') {
      this._memoryStore.set(sessionId, data);
      return;
    }

    if (this.type === 'file') {
      // Debounce 写操作，500ms 内的多次保存合并为一次
      if (this._writeTimeout) {
        clearTimeout(this._writeTimeout);
      }

      return new Promise((resolve, reject) => {
        this._writeQueue = { sessionId, data };
        this._writeTimeout = setTimeout(async () => {
          try {
            await this._writeToFile(this._writeQueue.sessionId, this._writeQueue.data);
            resolve();
          } catch (err) {
            reject(err);
          } finally {
            this._writeQueue = null;
            this._writeTimeout = null;
          }
        }, 500);
      });
    }
  }

  /**
   * 立即保存（不 debounce）
   * @param {string} sessionId
   * @param {Object} data
   */
  async saveImmediate(sessionId, data) {
    if (this._writeTimeout) {
      clearTimeout(this._writeTimeout);
      this._writeTimeout = null;
    }

    if (this.type === 'memory') {
      this._memoryStore.set(sessionId, data);
      return;
    }

    if (this.type === 'file') {
      await this._writeToFile(sessionId, data);
    }
  }

  /**
   * 写入文件
   * @param {string} sessionId
   * @param {Object} data
   * @private
   */
  async _writeToFile(sessionId, data) {
    const filePath = this._getFilePath(sessionId);

    try {
      // 确保目录存在
      const dir = path.dirname(filePath);
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
      }

      const content = JSON.stringify(data, null, 2);
      fs.writeFileSync(filePath, content, 'utf-8');
    } catch (err) {
      console.error(`[SessionStorage] Failed to write ${sessionId}:`, err.message);
      throw err;
    }
  }

  /**
   * 加载 Session 数据
   * @param {string} sessionId - 会话 ID
   * @returns {Promise<Object|null>}
   */
  async load(sessionId) {
    if (this.type === 'memory') {
      return this._memoryStore.get(sessionId) || null;
    }

    if (this.type === 'file') {
      const filePath = this._getFilePath(sessionId);

      if (!fs.existsSync(filePath)) {
        return null;
      }

      try {
        const content = fs.readFileSync(filePath, 'utf-8');
        return JSON.parse(content);
      } catch (err) {
        console.error(`[SessionStorage] Failed to read ${sessionId}:`, err.message);
        return null;
      }
    }

    return null;
  }

  /**
   * 删除 Session 数据
   * @param {string} sessionId - 会话 ID
   * @returns {Promise<boolean>}
   */
  async delete(sessionId) {
    if (this.type === 'memory') {
      return this._memoryStore.delete(sessionId);
    }

    if (this.type === 'file') {
      const filePath = this._getFilePath(sessionId);

      if (fs.existsSync(filePath)) {
        try {
          fs.unlinkSync(filePath);
          return true;
        } catch (err) {
          console.error(`[SessionStorage] Failed to delete ${sessionId}:`, err.message);
          return false;
        }
      }
      return false;
    }

    return false;
  }

  /**
   * 列出所有 Session ID
   * @returns {Promise<string[]>}
   */
  async list() {
    if (this.type === 'memory') {
      return Array.from(this._memoryStore.keys());
    }

    if (this.type === 'file') {
      const dir = path.resolve(process.cwd(), this.baseDir);

      if (!fs.existsSync(dir)) {
        return [];
      }

      try {
        const files = fs.readdirSync(dir);
        return files.filter((f) => f.endsWith('.json')).map((f) => f.replace(/\.json$/, ''));
      } catch (err) {
        console.error(`[SessionStorage] Failed to list sessions:`, err.message);
        return [];
      }
    }

    return [];
  }

  /**
   * 强制刷新所有待处理的写操作
   */
  async flush() {
    if (this._writeTimeout) {
      clearTimeout(this._writeTimeout);
      this._writeTimeout = null;

      if (this._writeQueue) {
        await this._writeToFile(this._writeQueue.sessionId, this._writeQueue.data);
        this._writeQueue = null;
      }
    }
  }

  /**
   * 销毁存储适配器
   */
  async destroy() {
    await this.flush();
    this._memoryStore.clear();
  }
}

/**
 * 全局默认存储适配器实例
 */
let _defaultAdapter = null;

/**
 * 获取默认存储适配器
 * @param {Object} options - 配置选项
 * @returns {SessionStorageAdapter}
 */
function getDefaultAdapter(options = {}) {
  if (!_defaultAdapter) {
    _defaultAdapter = new SessionStorageAdapter(options);
  }
  return _defaultAdapter;
}

/**
 * 设置默认存储适配器
 * @param {SessionStorageAdapter} adapter
 */
function setDefaultAdapter(adapter) {
  _defaultAdapter = adapter;
}

module.exports = {
  SessionStorageAdapter,
  getDefaultAdapter,
  setDefaultAdapter,
};
