/**
 * Email 插件
 * 邮件收发插件 - 支持读取和发送电子邮件、监控新邮件
 */

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

// 导入子模块
const { sendEmail, readEmails, getUnreadCount, markAsRead, deleteEmail, getEmailConfig } = require('./handlers')
const { handleEmailWatch } = require('./monitor')
const { handleAutoReply } = require('./reply')
const { EMAIL_DEFAULTS } = require('./constants')

class EmailPlugin extends Plugin {
  constructor(config = {}) {
    super()
    this.name = 'email'
    this.version = '1.1.0'
    this.description = `邮件收发插件 - 支持读取和发送电子邮件、监控新邮件
功能：
- 发送邮件支持附件（本地文件、远程URL、Base64）
- 读取邮件（IMAP协议）
- 监控新邮件（支持IMAP IDLE推送和定时轮询）
发送邮件支持附件：
- attachments.path: 本地文件路径
- attachments.url: 远程图片/文件URL（自动下载）
- attachments.content: Base64内容
- attachments.cid: 嵌入式图片CID（HTML中用 <img src="cid:xxx"> 引用）`
    this.priority = 10
    this.enabled = false

    // 邮件监控状态
    this._watchInterval = null
    this._lastSeenUid = null
    this._watchConfig = null
    this._watchEnabled = false
    this._checkInProgress = false

    // 带上限的 Set，防止内存泄漏
    const MAX_SET_SIZE = 1000
    this._recentlyEmailed = new Set()
    this._processedEmails = new Set()
    this._maxSetSize = MAX_SET_SIZE

    // 日志器
    this._log = log
  }

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

  start(framework) {
    return this
  }

  /**
   * 向 Set 中添加元素，自动控制大小防止内存泄漏
   * @param {Set} set - 要操作的 Set
   * @param {*} item - 要添加的元素
   * @private
   */
  _addToBoundedSet(set, item) {
    if (set.size >= this._maxSetSize) {
      // 删除最早的元素（Set 的插入顺序）
      const firstKey = set.values().next().value
      set.delete(firstKey)
    }
    set.add(item)
  }

  /**
   * 发送邮件事件
   */
  _emitEmailReceived(email) {
    if (!this._framework) return

    const msgId = email.messageId || email.uid

    // 优先检查是否已处理过（长TTL，防止服务器标记失败导致重复处理）
    if (msgId && this._processedEmails.has(msgId)) {
      this._log.info(`跳过已处理的邮件: ${email.subject} (${msgId})`)
      return
    }

    // 快速去重（短TTL，防止同一批次重复触发）
    if (msgId && this._recentlyEmailed.has(msgId)) {
      return
    }

    // 标记为已处理
    if (msgId) {
      // 使用 bounded set 防止内存泄漏
      this._addToBoundedSet(this._recentlyEmailed, msgId)
      setTimeout(() => {
        this._recentlyEmailed.delete(msgId)
      }, EMAIL_DEFAULTS.recentlyEmailTTL)

      // _processedEmails 也需要 bounded
      this._addToBoundedSet(this._processedEmails, msgId)
    }

    this._framework.emit('email:received', {
      email,
      timestamp: new Date()
    })
  }

  _registerTools() {
    // 发送邮件工具
    this._framework.registerTool({
      name: 'email_send',
      description: '发送电子邮件,无须用户确认',
      inputSchema: z.object({
        to: z.string().describe('收件人邮箱地址'),
        subject: z.string().describe('邮件主题'),
        body: z.string().describe('邮件正文内容'),
        cc: z.string().optional().describe('抄送邮箱地址，多个用逗号分隔'),
        bcc: z.string().optional().describe('密送邮箱地址，多个用逗号分隔'),
        isHtml: z.boolean().optional().describe('是否为HTML格式，默认false'),
        attachments: z.array(z.object({
          filename: z.string().describe('附件文件名'),
          path: z.string().optional().describe('本地文件路径'),
          url: z.string().optional().describe('远程图片URL'),
          content: z.string().optional().describe('Base64编码内容（可带前缀如 data:image/png;base64,）'),
          cid: z.string().optional().describe('嵌入式图片的CID（用于在HTML中嵌入图片，如 <img src="cid:xxx">）')
        })).optional().describe('附件列表，支持本地文件、远程URL或Base64内容')
      }),
      execute: async (args) => {
        return sendEmail(this, args)
      }
    })

    // 读取邮件工具
    this._framework.registerTool({
      name: 'email_read',
      description: '读取电子邮件（支持IMAP协议）',
      inputSchema: z.object({
        box: z.string().optional().describe('邮箱文件夹，默认INBOX'),
        limit: z.number().optional().describe('读取邮件数量，默认10'),
        unreadOnly: z.boolean().optional().describe('仅读取未读邮件，默认false'),
        searchCriteria: z.string().optional().describe('搜索条件，如 "UNSEEN", "FROM sender@example.com"')
      }),
      execute: async (args) => {
        return readEmails(this, args)
      }
    })

    // 获取未读邮件数量
    this._framework.registerTool({
      name: 'email_unread_count',
      description: '获取邮箱未读邮件数量',
      inputSchema: z.object({
        box: z.string().optional().describe('邮箱文件夹，默认INBOX')
      }),
      execute: async (args) => {
        return getUnreadCount(this, args)
      }
    })

    // 标记邮件为已读
    this._framework.registerTool({
      name: 'email_mark_read',
      description: '标记邮件为已读',
      inputSchema: z.object({
        messageId: z.string().describe('邮件UID或序列号')
      }),
      execute: async (args) => {
        return markAsRead(this, args)
      }
    })

    // 删除邮件
    this._framework.registerTool({
      name: 'email_delete',
      description: '删除邮件（标记为已删除，然后永久删除）',
      inputSchema: z.object({
        messageId: z.string().describe('邮件UID或序列号'),
        box: z.string().optional().describe('邮箱文件夹，默认INBOX')
      }),
      execute: async (args) => {
        return deleteEmail(this, args)
      }
    })

    // 配置邮箱连接
    this._framework.registerTool({
      name: 'email_configure',
      description: '查看邮箱配置（实际配置通过环境变量设置）',
      inputSchema: z.object({}),
      execute: async () => {
        return getEmailConfig()
      }
    })

    // 监控新邮件
    this._framework.registerTool({
      name: 'email_watch',
      description: '启动/停止邮件监控，检测新邮件并发送事件通知',
      inputSchema: z.object({
        action: z.enum(['start', 'stop', 'status']).describe('操作：启动监控、停止监控、查看状态'),
        interval: z.number().optional().describe('轮询间隔（秒），默认60秒，适用于不支持IDLE的服务器'),
        box: z.string().optional().describe('邮箱文件夹，默认INBOX')
      }),
      execute: async (args) => {
        return handleEmailWatch(this, args)
      }
    })

    // 自动回复邮件
    this._framework.registerTool({
      name: 'email_auto_reply',
      description: '自动分析邮件内容并发送回复（无需用户确认）',
      inputSchema: z.object({
        to: z.string().describe('收件人邮箱地址'),
        subject: z.string().describe('原始邮件主题'),
        body: z.string().describe('原始邮件内容'),
        from: z.string().optional().describe('发件人邮箱地址（可选）'),
        prompt: z.string().optional().describe('自定义提示词，用于指导AI生成回复内容'),
        timeout: z.number().optional().describe('AI生成回复超时时间（毫秒），默认60000'),
        messageId: z.string().optional().describe('原始邮件的Message-ID，用于在邮件客户端中创建回复线程')
      }),
      execute: async (args) => {
        return handleAutoReply(this, args)
      }
    })
  }

  /**
   * 启动邮件监控（内部方法）
   */
  _startEmailWatch(config) {
    const { startEmailWatch } = require('./monitor')
    return startEmailWatch(this, config)
  }

  /**
   * 停止邮件监控（内部方法）
   */
  _stopEmailWatch() {
    const { stopEmailWatch } = require('./monitor')
    return stopEmailWatch(this)
  }

  /**
   * 获取监控状态（内部方法）
   */
  _getEmailWatchStatus() {
    const { getEmailWatchStatus } = require('./monitor')
    return getEmailWatchStatus(this)
  }

  /**
   * 检查新邮件（内部方法）
   */
  async _checkNewEmails() {
    const { checkNewEmails } = require('./monitor')
    return checkNewEmails(this)
  }

  uninstall(framework) {
    // 停止邮件监控
    if (this._watchInterval) {
      clearInterval(this._watchInterval)
      this._watchInterval = null
    }
    this._watchEnabled = false
    this._watchConfig = null
    this._framework = null
  }
}

module.exports = EmailPlugin
