/**
 * Email 插件 - 邮件处理器
 */

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

/**
 * 创建 IMAP 配置
 * @param {Object} config - 用户配置
 * @returns {Object} 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 实例
 * @param {Object} args - 发送参数
 * @returns {Promise<Object>} 发送结果
 */
async function sendEmail(emailPlugin, args) {
  try {
    const nodemailer = require('nodemailer')
    const { DEFAULT_SMTP } = require('./constants')

    const smtpConfig = {
      ...DEFAULT_SMTP,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
      }
    }

    const transporter = nodemailer.createTransport(smtpConfig)

    const mailOptions = {
      from: process.env.FROM_EMAIL || smtpConfig.auth.user,
      to: args.to,
      subject: args.subject,
      text: args.isHtml ? undefined : args.body,
      html: args.isHtml ? args.body : undefined,
      cc: args.cc,
      bcc: args.bcc,
      inReplyTo: args.inReplyTo,
      references: args.references
    }

    // 处理附件
    if (args.attachments && args.attachments.length > 0) {
      mailOptions.attachments = []
      for (const att of args.attachments) {
        const processed = await processAttachment(att)
        mailOptions.attachments.push(processed)
      }
    }

    const info = await transporter.sendMail(mailOptions)
    return {
      success: true,
      message: '邮件发送成功',
      messageId: info.messageId,
      accepted: info.accepted,
      rejected: info.rejected
    }
  } catch (error) {
    return {
      success: false,
      error: error.message,
      details: '请检查 SMTP 配置是否正确'
    }
  }
}

/**
 * 读取邮件
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} args - 读取参数
 * @returns {Promise<Object>} 读取结果
 */
async function readEmails(emailPlugin, args) {
  try {
    const box = args.box || 'INBOX'
    const limit = args.limit || 10
    const unreadOnly = args.unreadOnly || false

    const imapConfig = createImapConfig(args)
    const emails = await fetchEmails(imapConfig, box, limit, unreadOnly, args.searchCriteria)

    return {
      success: true,
      count: emails.length,
      emails
    }
  } catch (error) {
    return {
      success: false,
      error: error.message,
      details: '请检查 IMAP 配置是否正确'
    }
  }
}

/**
 * 获取未读邮件数量
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} args - 参数
 * @returns {Promise<Object>} 未读数量
 */
async function getUnreadCount(emailPlugin, args) {
  try {
    const imapConfig = createImapConfig(args)
    const box = args.box || 'INBOX'
    const count = await fetchUnreadCount(imapConfig, box)

    return {
      success: true,
      unreadCount: count,
      box
    }
  } catch (error) {
    return {
      success: false,
      error: error.message
    }
  }
}

/**
 * 标记邮件为已读
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} args - 参数 { uid: 邮件UID }
 * @returns {Promise<Object>} 操作结果
 */
async function markAsRead(emailPlugin, args) {
  try {
    const imapConfig = createImapConfig(args)
    await markEmailAsRead(imapConfig, args.uid)

    return {
      success: true,
      message: '邮件已标记为已读'
    }
  } catch (error) {
    return {
      success: false,
      error: error.message
    }
  }
}

/**
 * 删除邮件
 * @param {Object} emailPlugin - EmailPlugin 实例
 * @param {Object} args - 参数 { uid: 邮件UID, box?: 文件夹 }
 * @returns {Promise<Object>} 操作结果
 */
async function deleteEmail(emailPlugin, args) {
  try {
    const messageId = args.messageId || args.uid
    if (!messageId) {
      return {
        success: false,
        error: 'messageId 是必填参数'
      }
    }

    const imapConfig = createImapConfig(args)
    const box = args.box || 'INBOX'
    await moveToTrash(imapConfig, box, messageId)

    return {
      success: true,
      message: '邮件已删除'
    }
  } catch (error) {
    return {
      success: false,
      error: error.message
    }
  }
}

/**
 * 获取邮箱配置信息
 * @returns {Object} 配置信息
 */
function getEmailConfig() {
  return {
    success: true,
    message: '邮箱配置通过环境变量设置',
    config: {
      smtp_host: process.env.SMTP_HOST || 'smtp.gmail.com',
      smtp_port: process.env.SMTP_PORT || 587,
      smtp_secure: process.env.SMTP_SECURE || 'false',
      imap_host: process.env.IMAP_HOST || 'imap.gmail.com',
      imap_port: process.env.IMAP_PORT || 993,
      from_email: process.env.FROM_EMAIL || '(未设置)',
      client_name: process.env.IMAP_CLIENT_NAME || 'FolikoAgent',
      client_version: process.env.IMAP_CLIENT_VERSION || '1.0.0'
    }
  }
}

// ============ 内部方法 ============

/**
 * 获取邮件列表
 */
function fetchEmails(imapConfig, box, limit, unreadOnly, searchCriteria) {
  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)
    const emails = []

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

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

        let searchFilter = searchCriteria
          ? searchCriteria.split(' ').filter(Boolean)
          : ['ALL']
        if (unreadOnly) {
          searchFilter = ['UNSEEN']
        }

        imap.search(searchFilter, (err, results) => {
          if (err) {
            cleanup()
            return reject(err)
          }

          if (!results || results.length === 0) {
            cleanup()
            return resolve([])
          }

          const fetchIds = results.slice(-limit)
          const f = imap.fetch(fetchIds, { bodies: '' })

          f.on('message', (msg) => {
            let email = {}
            let bodyParsed = false
            let uid = null  // 在 attributes 事件中获取 UID

            // 先获取 UID（比 body 更可靠）
            msg.on('attributes', (attrs) => {
              uid = attrs.uid
              email.uid = uid
              email.id = uid
              email.flags = attrs.flags
            })

            msg.on('body', (stream) => {
              simpleParser(stream).then(mail => {
                // 确保 uid 已设置（如果 attributes 先触发）
                if (!email.uid && uid) {
                  email.uid = uid
                  email.id = uid
                }
                email.subject = mail.subject
                email.from = mail.from?.text || ''
                email.to = mail.to?.text || ''
                email.date = mail.date?.toISOString() || ''
                email.text = mail.text || mail.textAsHtml || ''
                email.html = mail.html
                email.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) {
                  // 再次确保 uid 已设置
                  if (!email.uid && uid) {
                    email.uid = uid
                    email.id = uid
                  }
                  emails.push(email)
                } else {
                  setTimeout(checkDone, 10)
                }
              }
              checkDone()
            })
          })

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

          f.on('end', () => {
            // 添加超时保护，避免永久等待
            const timeoutMs = 30000
            const startTime = Date.now()
            
            const waitForAll = () => {
              if (emails.length === fetchIds.length) {
                cleanup()
                resolve(emails)
              } else if (Date.now() - startTime > timeoutMs) {
                cleanup()
                resolve(emails)  // 返回已获取的邮件
              } else {
                setTimeout(waitForAll, 50)
              }
            }
            waitForAll()
          })
        })
      })
    })

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

    imap.connect()
  })
}

/**
 * 获取未读邮件数量
 */
function fetchUnreadCount(imapConfig, box) {
  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)

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

    imap.on('ready', () => {
      imap.openBox(box, true, (err, boxObj) => {
        if (err) {
          cleanup()
          return reject(err)
        }
        const unreadCount = boxObj.messages.unread
        cleanup()
        resolve(unreadCount)
      })
    })

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

    imap.connect()
  })
}

/**
 * 标记邮件为已读
 * @param {Object} imapConfig - IMAP 配置
 * @param {number|string} uid - 邮件 UID
 */
function markEmailAsRead(imapConfig, uid) {
  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)

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

    imap.on('ready', () => {
      imap.openBox('INBOX', true, (err) => {
        if (err) {
          cleanup()
          return reject(err)
        }
        imap.addFlags(uid, '\\Seen', (err) => {
          cleanup()
          if (err) reject(err)
          else resolve()
        })
      })
    })

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

    imap.connect()
  })
}

/**
 * 移动邮件到垃圾箱
 * @param {Object} imapConfig - IMAP 配置
 * @param {string} box - 邮箱文件夹
 * @param {number|string} uid - 邮件 UID
 */
function moveToTrash(imapConfig, box, uid) {
  return new Promise((resolve, reject) => {
    const imap = new Imap(imapConfig)

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

    imap.on('ready', () => {
      imap.openBox(box, true, (err) => {
        if (err) {
          cleanup()
          return reject(err)
        }
        // 标记邮件为已删除
        imap.addFlags(uid, '\\Deleted', (err) => {
          if (err) {
            cleanup()
            return reject(err)
          }
          // 执行 expunge 永久删除
          imap.expunge((err) => {
            cleanup()
            if (err) reject(err)
            else resolve()
          })
        })
      })
    })

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

    imap.connect()
  })
}

module.exports = {
  sendEmail,
  readEmails,
  getUnreadCount,
  markAsRead,
  deleteEmail,
  getEmailConfig,
  createImapConfig
}
