/**
 * Storage 存储插件
 * 提供数据持久化存储，支持 JSON 文件存储
 */

const { Plugin } = require('../src/core/plugin-base')
const { logger } = require('../src/utils/logger')
const log = logger.child('Storage')
const { z } = require('zod')
const fs = require('fs')
const path = require('path')

class StoragePlugin extends Plugin {
  constructor(config = {}) {
    super()
    this.name = 'storage'
    this.version = '1.0.0'
    this.description = '数据持久化存储插件，支持键值对存储'
    this.priority = 3

    this.system = true 

    this.config = {
      type: config.type || 'json',  // json 或 memory
      path: config.path || '.agent/data',
      namespace: config.namespace || 'default'
    }

    this._framework = null
    this._store = new Map()
    this._filePath = null
  }

  install(framework) {
    this._framework = framework
    return this
  }

  start(framework) {
    // 初始化存储
    if (this.config.type === 'json') {
      this._initJsonStore()
    }

    // 注册存储工具
    framework.registerTool({
      name: 'storage_set',
      description: '存储数据到键值存储',
      inputSchema: z.object({
        key: z.string().describe('存储键名'),
        value: z.any().describe('存储值'),
        namespace: z.string().optional().describe('命名空间，默认使用全局命名空间')
      }),
      execute: async (args) => {
        try {
          const ns = args.namespace || this.config.namespace
          const fullKey = `${ns}:${args.key}`
          this._store.set(fullKey, {
            value: args.value,
            updatedAt: new Date()
          })

          if (this.config.type === 'json') {
            await this._persistToFile()
          }

          return { success: true, key: args.key, namespace: ns }
        } catch (err) {
          return { success: false, error: err.message }
        }
      }
    })

    framework.registerTool({
      name: 'storage_get',
      description: '从键值存储获取数据',
      inputSchema: z.object({
        key: z.string().describe('存储键名'),
        namespace: z.string().optional().describe('命名空间')
      }),
      execute: async (args) => {
        const ns = args.namespace || this.config.namespace
        const fullKey = `${ns}:${args.key}`
        const entry = this._store.get(fullKey)

        if (!entry) {
          return { success: false, error: 'Key not found', key: args.key }
        }

        return {
          success: true,
          key: args.key,
          namespace: ns,
          value: entry.value,
          updatedAt: entry.updatedAt
        }
      }
    })

    framework.registerTool({
      name: 'storage_delete',
      description: '删除存储的数据',
      inputSchema: z.object({
        key: z.string().describe('存储键名'),
        namespace: z.string().optional().describe('命名空间')
      }),
      execute: async (args) => {
        const ns = args.namespace || this.config.namespace
        const fullKey = `${ns}:${args.key}`
        const existed = this._store.has(fullKey)
        this._store.delete(fullKey)

        if (this.config.type === 'json') {
          await this._persistToFile()
        }

        return { success: true, deleted: existed, key: args.key }
      }
    })

    framework.registerTool({
      name: 'storage_list',
      description: '列出命名空间下的所有键',
      inputSchema: z.object({
        namespace: z.string().optional().describe('命名空间，默认全局')
      }),
      execute: async (args) => {
        const ns = args.namespace || this.config.namespace
        const prefix = `${ns}:`
        const keys = []

        for (const key of this._store.keys()) {
          if (key.startsWith(prefix)) {
            keys.push(key.substring(prefix.length))
          }
        }

        return {
          success: true,
          namespace: ns,
          keys,
          count: keys.length
        }
      }
    })

    framework.registerTool({
      name: 'storage_clear',
      description: '清空命名空间下的所有数据',
      inputSchema: z.object({
        namespace: z.string().optional().describe('命名空间，默认全局')
      }),
      execute: async (args) => {
        const ns = args.namespace || this.config.namespace
        const prefix = `${ns}:`
        let count = 0

        for (const key of this._store.keys()) {
          if (key.startsWith(prefix)) {
            this._store.delete(key)
            count++
          }
        }

        if (this.config.type === 'json') {
          await this._persistToFile()
        }

        return { success: true, namespace: ns, cleared: count }
      }
    })

    return this
  }

  /**
   * 初始化 JSON 文件存储
   */
  _initJsonStore() {
    this._filePath = path.resolve(process.cwd(), this.config.path, `${this.config.namespace}.json`)

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

    // 加载已有数据
    if (fs.existsSync(this._filePath)) {
      try {
        const content = fs.readFileSync(this._filePath, 'utf-8')
        const data = JSON.parse(content)

        for (const [key, entry] of Object.entries(data)) {
          this._store.set(key, entry)
        }

        log.info(` Loaded ${this._store.size} entries from ${this._filePath}`)
      } catch (err) {
        log.warn(` Failed to load storage file: ${err.message}`)
      }
    }
  }

  /**
   * 持久化到文件
   */
  async _persistToFile() {
    if (!this._filePath) return

    try {
      const data = Object.fromEntries(this._store)
      fs.writeFileSync(this._filePath, JSON.stringify(data, null, 2), 'utf-8')
    } catch (err) {
      log.error(` Failed to persist: ${err.message}`)
    }
  }

  /**
   * 获取存储实例（供其他插件使用）
   */
  getStore() {
    return this._store
  }

  /**
   * 直接设置值并自动持久化（供其他插件使用）
   * @param {string} key - 键
   * @param {any} value - 值
   */
  setDirect(key, value) {
    this._store.set(key, value)
    if (this.config.type === 'json') {
      this._persistToFile()
    }
  }

  /**
   * 删除键并自动持久化（供其他插件使用）
   * @param {string} key - 键
   */
  deleteDirect(key) {
    this._store.delete(key)
    if (this.config.type === 'json') {
      this._persistToFile()
    }
  }

  reload(framework) {
    this._framework = framework
    this._store.clear()

    if (this.config.type === 'json') {
      this._initJsonStore()
    }
  }

  uninstall(framework) {
    this._store.clear()
    this._framework = null
  }
}

module.exports = StoragePlugin