const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const nodemailer = require('nodemailer');
const dotenv = require('dotenv');

// 加载环境变量
dotenv.config();

const app = express();
const port = process.env.PORT || 3001;

// 中间件
app.use(cors({
  origin: '*',  // 允许所有来源访问
  methods: ['GET', 'POST', 'OPTIONS'],  // 允许的HTTP方法
  allowedHeaders: ['Content-Type', 'Authorization'],  // 允许的请求头
  credentials: true  // 允许发送凭证
}));
app.use(bodyParser.json());

// 处理OPTIONS预检请求
app.options('*', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Max-Age', '86400'); // 24小时
  res.sendStatus(204);
});

// 创建Nodemailer传输器
const transporter = nodemailer.createTransport({
  service: process.env.EMAIL_SERVICE || 'smtp', // 邮件服务商，例如：'gmail', 'qq', '163'等
  host: process.env.EMAIL_HOST || 'smtp.163.com', // SMTP服务器
  port: parseInt(process.env.EMAIL_PORT || '587'),
  secure: process.env.EMAIL_SECURE === 'true', // true for 465, false for other ports
  auth: {
    user: process.env.EMAIL_USER || '', // 发送方邮箱
    pass: process.env.EMAIL_PASS || '', // 授权码或密码
  },
  // 增加连接超时设置
  connectionTimeout: 10000, // 10秒连接超时
  greetingTimeout: 10000,  // 10秒问候超时
  socketTimeout: 15000,    // 15秒socket超时
  // 增加重试选项
  pool: true,              // 使用连接池
  maxConnections: 5,       // 最大连接数
  maxMessages: 100,        // 每个连接最大消息数
  // 调试选项
  debug: true,             // 启用调试日志
});

// 验证传输器连接
transporter.verify(function(error, success) {
  if (error) {
    console.error('SMTP连接验证失败:', error);
  } else {
    console.log('SMTP服务器连接成功，准备发送邮件');
  }
});

// 存储IP地址最后发送邮件的时间
const lastEmailSentTime = new Map();

// 速率限制中间件 - 60秒内只能发送一封邮件
const rateLimitMiddleware = (req, res, next) => {
  const ip = req.ip || req.connection.remoteAddress;
  const currentTime = Date.now();
  const lastTime = lastEmailSentTime.get(ip) || 0;
  const timeDiff = currentTime - lastTime;
  
  // 如果距离上次发送不足60秒，则拒绝请求
  if (lastTime && timeDiff < 60000) {
    const remainingTime = Math.ceil((60000 - timeDiff) / 1000);
    return res.status(429).json({ 
      error: `请求过于频繁，请在${remainingTime}秒后再试`,
      remainingTime
    });
  }
  
  // 更新最后发送时间并继续处理请求
  lastEmailSentTime.set(ip, currentTime);
  next();
};

// 邮件发送接口
app.post('/api/send-email', rateLimitMiddleware, async (req, res) => {
  const { name, email, subject, message } = req.body;

  if (!name || !email || !message) {
    return res.status(400).json({ error: '请填写所有必填字段' });
  }

  // 邮件选项
  const mailOptions = {
    from: `"个人网站联系表单" <${process.env.EMAIL_USER}>`,
    to: process.env.EMAIL_RECIPIENT || process.env.EMAIL_USER, // 接收方邮箱
    subject: subject ? `新的联系表单消息: ${subject}` : '新的联系表单消息',
    html: `
      <h3>您有一条新的联系表单消息</h3>
      <p><strong>姓名:</strong> ${name}</p>
      <p><strong>邮箱:</strong> ${email}</p>
      <p><strong>主题:</strong> ${subject || '无'}</p>
      <p><strong>消息:</strong></p>
      <p>${message.replace(/\n/g, '<br>')}</p>
    `,
    // 回复选项，回复时会发送到表单提交者的邮箱
    replyTo: email
  };

  // 最大重试次数
  const maxRetries = 3;
  let retries = 0;
  let lastError = null;

  // 重试发送邮件的函数
  const attemptSendMail = async () => {
    try {
      const info = await transporter.sendMail(mailOptions);
      console.log('邮件发送成功:', info.messageId);
      return true;
    } catch (error) {
      lastError = error;
      console.error(`发送邮件失败 (尝试 ${retries + 1}/${maxRetries}):`, error);
      return false;
    }
  };

  try {
    // 尝试发送邮件，最多重试maxRetries次
    let success = false;
    while (retries < maxRetries && !success) {
      success = await attemptSendMail();
      if (!success) {
        retries++;
        if (retries < maxRetries) {
          // 等待一段时间后重试，每次等待时间增加
          const waitTime = 1000 * retries; // 1秒, 2秒, 3秒...
          console.log(`等待 ${waitTime}ms 后重试...`);
          await new Promise(resolve => setTimeout(resolve, waitTime));
        }
      }
    }

    if (success) {
      return res.status(200).json({ success: true, message: '邮件已成功发送' });
    } else {
      // 所有重试都失败了
      console.error('所有重试都失败，最后一个错误:', lastError);
      return res.status(500).json({ 
        error: '发送邮件失败，请稍后再试',
        details: lastError ? lastError.message : '未知错误'
      });
    }
  } catch (error) {
    console.error('发送邮件过程中出现异常:', error);
    return res.status(500).json({ 
      error: '发送邮件过程中出现异常',
      details: error.message
    });
  }
});

// 测试路由
app.get('/api/test', (req, res) => {
  res.json({ message: 'API服务器运行正常' });
});

// 启动服务器
app.listen(port, () => {
  console.log(`邮件服务API正在端口 ${port} 上运行`);
}); 