/**
 * Email 插件 - 邮件监控
 */

const Imap = require('imap-mkl')
const { simpleParser } = require('mailparser')
const { DEFAULT_IMAP, IMAP_CLIENT_INFO, EMAIL_DEFAULTS } = require('./constants')
const { getConfig, generateCallId } = require('./utils')

/**
 * 创建 IMAP 配置
 */
function createImapConfig(config = {}) {
  const cfg = getConfig(config)
  return {
    ...DEFAULT_IMAP,
    user: cfg.user,
    password: cfg.password,
    host: cfg.host,
    port: cfg.port,
    id: IMAP_CLIENT_INFO
  }
}

/**
 * 标记所有现有未读邮件为已读（启动监控前调用）
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @returns {Promise<number>} 标记的邮件数量
 */
async function markAllExistingUnreadAsRead(emailPlugin) {
  const config = emailPlugin._watchConfig
  if (!config) return 0

  const imapConfig = createImapConfig(config)
  const box = config.box || 'INBOX'

  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)

    imap.on('ready', () => {
      imap.openBox(box, false, (err, boxData) => {
        if (err) {
          imap.end()
          return reject(err)
        }

        // 搜索所有 UNSEEN 邮件
        imap.search(['UNSEEN'], (err, results) => {
          if (err) {
            imap.end()
            return reject(err)
          }

          if (!results || results.length === 0) {
            imap.end()
            emailPlugin._log.info(` 没有现有未读邮件需要标记`)
            return resolve(0)
          }

          emailPlugin._log.info(` 发现 ${results.length} 封现有未读邮件，开始标记为已读...`)

          // 批量标记为已读
          if (results.length > 0) {
            imap.setFlags(results, '\\Seen', (err) => {
              if (err) {
                emailPlugin._log.warn(` 标记已读失败: ${err.message}`)
              } else {
                emailPlugin._log.info(` 已标记 ${results.length} 封邮件为已读`)
              }
              imap.end()
              resolve(results.length)
            })
          } else {
            imap.end()
            resolve(0)
          }
        })
      })
    })

    imap.on('error', (err) => {
      reject(err)
    })

    imap.connect()
  })
}

/**
 * 处理邮件监控
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} args - 参数
 * @returns {Object} 操作结果
 */
function handleEmailWatch(emailPlugin, args) {
  const { action, interval, box } = args

  switch (action) {
    case 'start':
      return emailPlugin._startEmailWatch({ interval, box })

    case 'stop':
      return emailPlugin._stopEmailWatch()

    case 'status':
      return emailPlugin._getEmailWatchStatus()

    default:
      return { success: false, error: `Unknown action: ${action}` }
  }
}

/**
 * 启动邮件监控
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} config - 监控配置
 * @returns {Object} 操作结果
 */
async function startEmailWatch(emailPlugin, config) {
  if (emailPlugin._watchEnabled) {
    return { success: false, error: 'Email watch is already running' }
  }

  emailPlugin._watchConfig = {
    host: config.host || process.env.IMAP_HOST,
    port: config.port || parseInt(process.env.IMAP_PORT) || 993,
    user: config.user || process.env.IMAP_USER,
    password: config.password || process.env.IMAP_PASS,
    box: config.box || 'INBOX',
    interval: (config.interval || EMAIL_DEFAULTS.interval) * 1000
  }

  if (!emailPlugin._watchConfig.user || !emailPlugin._watchConfig.password) {
    return { success: false, error: 'IMAP user/password is required' }
  }

  emailPlugin._watchEnabled = true

  // 启动监控前，先标记所有现有未读邮件为已读
  try {
    await markAllExistingUnreadAsRead(emailPlugin)
  } catch (err) {
    emailPlugin._log.warn(' 标记现有邮件已读失败，继续监控:', err.message)
  }

  // 立即执行一次检查
  emailPlugin._checkNewEmails().catch(err => {
    emailPlugin._log.error('Initial check failed:', err.message)
  })

  // 启动轮询
  emailPlugin._watchInterval = setInterval(() => {
    emailPlugin._checkNewEmails().catch(err => {
      emailPlugin._log.error('Watch check failed:', err.message)
    })
  }, emailPlugin._watchConfig.interval)

  return {
    success: true,
    message: `Email watch started (interval: ${emailPlugin._watchConfig.interval / 1000}s)`,
    config: {
      host: emailPlugin._watchConfig.host,
      box: emailPlugin._watchConfig.box,
      interval: emailPlugin._watchConfig.interval / 1000
    }
  }
}

/**
 * 停止邮件监控
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @returns {Object} 操作结果
 */
function stopEmailWatch(emailPlugin) {
  if (!emailPlugin._watchEnabled) {
    return { success: false, error: 'Email watch is not running' }
  }

  if (emailPlugin._watchInterval) {
    clearInterval(emailPlugin._watchInterval)
    emailPlugin._watchInterval = null
  }

  emailPlugin._watchEnabled = false
  emailPlugin._watchConfig = null

  return { success: true, message: 'Email watch stopped' }
}

/**
 * 获取监控状态
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @returns {Object} 状态信息
 */
function getEmailWatchStatus(emailPlugin) {
  return {
    success: true,
    watching: emailPlugin._watchEnabled,
    config: emailPlugin._watchConfig ? {
      host: emailPlugin._watchConfig.host,
      box: emailPlugin._watchConfig.box,
      interval: emailPlugin._watchConfig.interval / 1000,
      lastSeenUid: emailPlugin._lastSeenUid
    } : null
  }
}

/**
 * 检查新邮件
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @returns {Promise<Object>} 检查结果
 */
async function checkNewEmails(emailPlugin) {
  if (!emailPlugin._watchConfig) return

  const callId = generateCallId()
  //emailPlugin._log.info(`[Email] 开始检查新邮件...`)

  // 防止并发检查
  if (emailPlugin._checkInProgress) {
    emailPlugin._log.debug(`[${callId}] Skipping - already in progress`)
    return
  }
  emailPlugin._checkInProgress = true

  const imapConfig = createImapConfig(emailPlugin._watchConfig)

  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)

    const cleanup = () => {
      try { imap.end() } catch (e) {}
      emailPlugin._checkInProgress = false
    }

    imap.on('ready', () => {
      imap.openBox(emailPlugin._watchConfig.box, true, (err, box) => {
        if (err) {
          cleanup()
          return reject(err)
        }

        // 搜索未读邮件
        imap.search(['UNSEEN'], (err, results) => {
          if (err) {
            cleanup()
            return reject(err)
          }

          if (!results || results.length === 0) {
            emailPlugin._log.info(`[Email] 没有未读邮件`)
            cleanup()
            return resolve({ success: true, newEmails: 0 })
          }

          // 找出新的未读邮件
          const newEmails = results.filter(uid => 
            !emailPlugin._lastSeenUid || uid > emailPlugin._lastSeenUid
          )

          if (newEmails.length > 0) {
            emailPlugin._log.info(`[Email] 发现 ${newEmails.length} 封未读邮件，开始处理...`)
            const latestUid = Math.max(...newEmails)

            // 先更新 _lastSeenUid，防止重复检测
            emailPlugin._lastSeenUid = latestUid

            // imap.fetch() 需要 UIDs 数组，传单个数字会导致获取从该 UID 到末尾的所有邮件
            const f = imap.fetch([latestUid], { bodies: '' })

            f.on('message', (msg) => {
              let email = {}
              let bodyParsed = false

              msg.on('body', (stream) => {
                simpleParser(stream).then(mail => {
                  email = {
                    uid: mail.uid || latestUid,
                    messageId: mail.messageId,
                    subject: mail.subject,
                    from: mail.from?.text || '',
                    to: mail.to?.text || '',
                    date: mail.date?.toISOString() || '',
                    text: mail.text || mail.textAsHtml || '',
                    html: mail.html,
                    attachments: mail.attachments?.map(a => ({
                      filename: a.filename,
                      contentType: a.contentType
                    })) || []
                  }
                  bodyParsed = true
                }).catch(err => {
                  email.error = err.message
                  bodyParsed = true
                })
              })

              msg.on('end', () => {
                const checkDone = () => {
                  if (bodyParsed) {
                    // 发送事件通知
                    emailPlugin._emitEmailReceived(email)

                    cleanup()
                    resolve({ success: true, newEmails: newEmails.length, email })
                  } else {
                    setTimeout(checkDone, 10)
                  }
                }
                checkDone()
              })
            })

            f.on('error', (err) => {
              cleanup()
              reject(err)
            })
          } else {
            cleanup()
            resolve({ success: true, newEmails: 0 })
          }
        })
      })
    })

    imap.on('error', (err) => {
      cleanup()
      reject(err)
    })

    imap.on('end', () => {})

    imap.connect()
  })
}

module.exports = {
  handleEmailWatch,
  startEmailWatch,
  stopEmailWatch,
  getEmailWatchStatus,
  checkNewEmails
}
