/**
 * 通知服务
 * @file notificationService.js
 * @description 实现邮件/短信预警通知功能，确保5分钟内响应时间
 */
const nodemailer = require('nodemailer');
const logger = require('../utils/logger');
const { User, Farm } = require('../models');

class NotificationService {
  constructor() {
    this.emailTransporter = null;
    this.smsService = null; // 短信服务接口（后续可扩展）
    this.notificationQueue = []; // 通知队列
    this.isProcessing = false;
    this.maxRetries = 3;
    this.retryDelay = 1000; // 1秒重试延迟

    // 初始化邮件服务
    this.initEmailService();
  }

  /**
   * 初始化邮件服务
   */
  initEmailService() {
    try {
      // 配置邮件传输器（使用环境变量配置）
      this.emailTransporter = nodemailer.createTransport({
        host: process.env.SMTP_HOST || 'smtp.example.com',
        port: process.env.SMTP_PORT || 587,
        secure: false, // true for 465, false for other ports
        auth: {
          user: process.env.SMTP_USER || 'noreply@farm-monitor.com',
          pass: process.env.SMTP_PASS || 'your_email_password'
        },
        tls: {
          rejectUnauthorized: false
        }
      });

      logger.info('邮件服务初始化完成');
    } catch (error) {
      logger.error('邮件服务初始化失败:', error);
    }
  }

  /**
   * 发送预警通知
   * @param {Object} alert 预警对象
   * @param {Array} recipients 接收人列表
   * @param {Object} options 通知选项
   */
  async sendAlertNotification(alert, recipients = [], options = {}) {
    const {
      urgent = false,
      includeSMS = false,
      maxResponseTime = 300000 // 5分钟 = 300000毫秒
    } = options;

    const notification = {
      id: `alert_${alert.id}_${Date.now()}`,
      type: 'alert',
      alert,
      recipients,
      urgent,
      includeSMS,
      createdAt: new Date(),
      maxResponseTime,
      retryCount: 0,
      status: 'pending'
    };

    // 添加到通知队列
    this.notificationQueue.push(notification);

    // 立即处理紧急通知
    if (urgent) {
      await this.processNotification(notification);
    } else {
      // 非紧急通知进入队列处理
      this.processQueue();
    }

    logger.info(`预警通知已加入队列: ${notification.id}, 紧急程度: ${urgent}`);
    return notification.id;
  }

  /**
   * 处理通知队列
   */
  async processQueue() {
    if (this.isProcessing) return;

    this.isProcessing = true;

    try {
      while (this.notificationQueue.length > 0) {
        const notification = this.notificationQueue.shift();
        
        // 检查是否超时
        const timePassed = Date.now() - notification.createdAt.getTime();
        if (timePassed > notification.maxResponseTime) {
          logger.warn(`通知 ${notification.id} 已超时，跳过处理`);
          continue;
        }

        await this.processNotification(notification);
      }
    } catch (error) {
      logger.error('处理通知队列失败:', error);
    } finally {
      this.isProcessing = false;
    }
  }

  /**
   * 处理单个通知
   * @param {Object} notification 通知对象
   */
  async processNotification(notification) {
    try {
      const startTime = Date.now();

      // 获取接收人列表
      const recipients = await this.getNotificationRecipients(notification);

      // 发送邮件通知
      const emailResults = await this.sendEmailNotifications(notification, recipients);

      // 发送短信通知（如果需要）
      let smsResults = [];
      if (notification.includeSMS) {
        smsResults = await this.sendSMSNotifications(notification, recipients);
      }

      const endTime = Date.now();
      const responseTime = endTime - startTime;

      // 记录通知发送结果
      notification.status = 'completed';
      notification.responseTime = responseTime;
      notification.emailResults = emailResults;
      notification.smsResults = smsResults;

      logger.info(`通知 ${notification.id} 发送完成，响应时间: ${responseTime}ms`);

      // 检查是否超过5分钟响应时间要求
      if (responseTime > 300000) {
        logger.warn(`通知 ${notification.id} 响应时间超过5分钟: ${responseTime}ms`);
      }

    } catch (error) {
      logger.error(`处理通知 ${notification.id} 失败:`, error);
      
      // 重试机制
      if (notification.retryCount < this.maxRetries) {
        notification.retryCount++;
        notification.status = 'retrying';
        
        setTimeout(() => {
          this.notificationQueue.unshift(notification); // 重新加入队列头部
          this.processQueue();
        }, this.retryDelay * notification.retryCount);
        
        logger.info(`通知 ${notification.id} 将进行第 ${notification.retryCount} 次重试`);
      } else {
        notification.status = 'failed';
        logger.error(`通知 ${notification.id} 达到最大重试次数，标记为失败`);
      }
    }
  }

  /**
   * 获取通知接收人
   * @param {Object} notification 通知对象
   * @returns {Array} 接收人列表
   */
  async getNotificationRecipients(notification) {
    try {
      const alert = notification.alert;
      const recipients = [];

      // 如果指定了接收人，直接使用
      if (notification.recipients && notification.recipients.length > 0) {
        return notification.recipients;
      }

      // 获取农场相关负责人
      if (alert.farm_id) {
        const farm = await Farm.findByPk(alert.farm_id);
        if (farm && farm.contact) {
          recipients.push({
            name: farm.contact,
            email: `${farm.contact.toLowerCase().replace(/\s+/g, '')}@farm-monitor.com`,
            phone: farm.phone,
            role: 'farm_manager'
          });
        }
      }

      // 获取系统管理员
      const admins = await User.findAll({
        include: [{
          model: require('../models').Role,
          as: 'role',
          where: { name: 'admin' }
        }]
      });

      for (const admin of admins) {
        recipients.push({
          name: admin.username,
          email: admin.email,
          phone: admin.phone,
          role: 'admin'
        });
      }

      return recipients;
    } catch (error) {
      logger.error('获取通知接收人失败:', error);
      return [];
    }
  }

  /**
   * 发送邮件通知
   * @param {Object} notification 通知对象
   * @param {Array} recipients 接收人列表
   * @returns {Array} 发送结果
   */
  async sendEmailNotifications(notification, recipients) {
    if (!this.emailTransporter) {
      logger.warn('邮件服务未初始化，跳过邮件发送');
      return [];
    }

    const results = [];
    const alert = notification.alert;

    for (const recipient of recipients) {
      if (!recipient.email) continue;

      try {
        const emailContent = this.generateEmailContent(alert, recipient);
        
        const mailOptions = {
          from: process.env.SMTP_FROM || '"宁夏智慧养殖监管平台" <noreply@farm-monitor.com>',
          to: recipient.email,
          subject: emailContent.subject,
          html: emailContent.html,
          priority: alert.level === 'critical' ? 'high' : 'normal'
        };

        const result = await this.emailTransporter.sendMail(mailOptions);
        
        results.push({
          recipient: recipient.email,
          status: 'success',
          messageId: result.messageId
        });

        logger.info(`邮件通知发送成功: ${recipient.email}`);
      } catch (error) {
        results.push({
          recipient: recipient.email,
          status: 'failed',
          error: error.message
        });

        logger.error(`邮件通知发送失败: ${recipient.email}`, error);
      }
    }

    return results;
  }

  /**
   * 生成邮件内容
   * @param {Object} alert 预警对象
   * @param {Object} recipient 接收人信息
   * @returns {Object} 邮件内容
   */
  generateEmailContent(alert, recipient) {
    const levelMap = {
      low: { text: '低级', color: '#52c41a' },
      medium: { text: '中级', color: '#1890ff' },
      high: { text: '高级', color: '#fa8c16' },
      critical: { text: '紧急', color: '#f5222d' }
    };

    const levelInfo = levelMap[alert.level] || levelMap.medium;
    const urgentFlag = alert.level === 'critical' ? '🚨 ' : '';

    const subject = `${urgentFlag}宁夏智慧养殖监管平台 - ${levelInfo.text}预警通知`;

    const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center;">
          <h1 style="margin: 0;">宁夏智慧养殖监管平台</h1>
          <p style="margin: 5px 0 0 0;">智慧养殖 · 科学监管</p>
        </div>
        
        <div style="padding: 30px; background: #f8f9fa;">
          <h2 style="color: ${levelInfo.color}; margin-top: 0;">
            ${urgentFlag}${levelInfo.text}预警通知
          </h2>
          
          <div style="background: white; padding: 20px; border-radius: 8px; border-left: 4px solid ${levelInfo.color};">
            <p><strong>尊敬的 ${recipient.name}：</strong></p>
            <p>系统检测到以下预警信息，请及时处理：</p>
            
            <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold; width: 120px;">预警级别:</td>
                <td style="padding: 8px; color: ${levelInfo.color}; font-weight: bold;">${levelInfo.text}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">预警类型:</td>
                <td style="padding: 8px;">${alert.type}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">预警内容:</td>
                <td style="padding: 8px;">${alert.message}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">所属养殖场:</td>
                <td style="padding: 8px;">${alert.farm_name || '未知'}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">发生时间:</td>
                <td style="padding: 8px;">${new Date(alert.created_at).toLocaleString('zh-CN')}</td>
              </tr>
            </table>
            
            ${alert.level === 'critical' ? 
              '<div style="background: #fff2f0; border: 1px solid #ffccc7; padding: 15px; border-radius: 4px; color: #f5222d;"><strong>⚠️ 这是一个紧急预警，请立即处理！</strong></div>' : 
              '<p style="color: #666;">请及时登录系统查看详细信息并处理相关问题。</p>'
            }
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <a href="${process.env.FRONTEND_URL || 'http://localhost:5300'}/alerts" 
               style="background: ${levelInfo.color}; color: white; padding: 12px 30px; text-decoration: none; border-radius: 4px; font-weight: bold;">
              立即处理预警
            </a>
          </div>
        </div>
        
        <div style="background: #e9ecef; padding: 15px; text-align: center; color: #6c757d; font-size: 12px;">
          <p>此邮件由宁夏智慧养殖监管平台自动发送，请勿回复</p>
          <p>如需帮助，请联系系统管理员</p>
        </div>
      </div>
    `;

    return { subject, html };
  }

  /**
   * 发送短信通知（预留接口）
   * @param {Object} notification 通知对象
   * @param {Array} recipients 接收人列表
   * @returns {Array} 发送结果
   */
  async sendSMSNotifications(notification, recipients) {
    // 这里可以集成阿里云短信、腾讯云短信等服务
    const results = [];
    const alert = notification.alert;

    for (const recipient of recipients) {
      if (!recipient.phone) continue;

      try {
        // 短信内容
        const smsContent = `【宁夏智慧养殖监管平台】${alert.level === 'critical' ? '紧急' : ''}预警：${alert.message}。请及时处理。时间：${new Date().toLocaleString('zh-CN')}`;

        // 这里实现具体的短信发送逻辑
        // const smsResult = await this.sendSMS(recipient.phone, smsContent);
        
        // 目前记录到日志（实际部署时替换为真实短信服务）
        logger.info(`短信通知（模拟）已发送到 ${recipient.phone}: ${smsContent}`);
        
        results.push({
          recipient: recipient.phone,
          status: 'success',
          content: smsContent
        });

      } catch (error) {
        results.push({
          recipient: recipient.phone,
          status: 'failed',
          error: error.message
        });

        logger.error(`短信通知发送失败: ${recipient.phone}`, error);
      }
    }

    return results;
  }

  /**
   * 发送系统状态通知
   * @param {Object} statusData 系统状态数据
   * @param {Array} adminEmails 管理员邮箱列表
   */
  async sendSystemStatusNotification(statusData, adminEmails = []) {
    if (!this.emailTransporter) return;

    const subject = `宁夏智慧养殖监管平台 - 系统状态报告`;
    
    const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <div style="background: #1890ff; color: white; padding: 20px; text-align: center;">
          <h1 style="margin: 0;">系统状态报告</h1>
          <p style="margin: 5px 0 0 0;">宁夏智慧养殖监管平台</p>
        </div>
        
        <div style="padding: 30px; background: #f8f9fa;">
          <h2 style="color: #333; margin-top: 0;">系统运行状况</h2>
          
          <div style="background: white; padding: 20px; border-radius: 8px;">
            <table style="width: 100%; border-collapse: collapse;">
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">API响应时间:</td>
                <td style="padding: 8px;">${statusData.apiResponseTime || 'N/A'}ms</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">数据库连接状态:</td>
                <td style="padding: 8px;">${statusData.dbConnected ? '正常' : '异常'}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">系统内存使用率:</td>
                <td style="padding: 8px;">${statusData.memoryUsage || 'N/A'}%</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">活跃用户数:</td>
                <td style="padding: 8px;">${statusData.activeUsers || 0}</td>
              </tr>
              <tr>
                <td style="padding: 8px; background: #f1f3f4; font-weight: bold;">报告时间:</td>
                <td style="padding: 8px;">${new Date().toLocaleString('zh-CN')}</td>
              </tr>
            </table>
          </div>
        </div>
        
        <div style="background: #e9ecef; padding: 15px; text-align: center; color: #6c757d; font-size: 12px;">
          <p>此邮件由系统自动发送</p>
        </div>
      </div>
    `;

    for (const email of adminEmails) {
      try {
        await this.emailTransporter.sendMail({
          from: process.env.SMTP_FROM || '"宁夏智慧养殖监管平台" <noreply@farm-monitor.com>',
          to: email,
          subject,
          html
        });

        logger.info(`系统状态报告已发送到: ${email}`);
      } catch (error) {
        logger.error(`系统状态报告发送失败: ${email}`, error);
      }
    }
  }

  /**
   * 测试邮件服务
   * @param {string} testEmail 测试邮箱
   * @returns {boolean} 测试结果
   */
  async testEmailService(testEmail) {
    if (!this.emailTransporter) {
      logger.error('邮件服务未初始化');
      return false;
    }

    try {
      const result = await this.emailTransporter.sendMail({
        from: process.env.SMTP_FROM || '"宁夏智慧养殖监管平台" <noreply@farm-monitor.com>',
        to: testEmail,
        subject: '宁夏智慧养殖监管平台 - 邮件服务测试',
        html: `
          <div style="font-family: Arial, sans-serif; padding: 20px; text-align: center;">
            <h2 style="color: #1890ff;">邮件服务测试</h2>
            <p>如果您收到此邮件，说明邮件服务配置正确。</p>
            <p>测试时间: ${new Date().toLocaleString('zh-CN')}</p>
          </div>
        `
      });

      logger.info(`测试邮件发送成功: ${testEmail}, MessageID: ${result.messageId}`);
      return true;
    } catch (error) {
      logger.error(`测试邮件发送失败: ${testEmail}`, error);
      return false;
    }
  }

  /**
   * 获取通知统计信息
   * @returns {Object} 统计信息
   */
  getNotificationStats() {
    const completedNotifications = this.notificationQueue.filter(n => n.status === 'completed');
    const failedNotifications = this.notificationQueue.filter(n => n.status === 'failed');
    
    const avgResponseTime = completedNotifications.length > 0 
      ? completedNotifications.reduce((sum, n) => sum + n.responseTime, 0) / completedNotifications.length 
      : 0;

    return {
      totalNotifications: this.notificationQueue.length,
      completedCount: completedNotifications.length,
      failedCount: failedNotifications.length,
      avgResponseTime: Math.round(avgResponseTime),
      queueLength: this.notificationQueue.filter(n => n.status === 'pending').length
    };
  }
}

// 创建单例实例
const notificationService = new NotificationService();

module.exports = notificationService;
