const { DeviceAlert, Device, User } = require('../models');
const { Op } = require('sequelize');
const logger = require('../utils/logger');
const ExcelExport = require('../utils/excelExport');

/**
 * 设备预警控制器
 */
class DeviceAlertController {
  
  /**
   * 获取预警统计信息
   */
  static async getAlertStats(req, res) {
    try {
      const { farm_id, start_date, end_date } = req.query;
      
      // 构建查询条件
      const whereCondition = {};
      if (farm_id) {
        whereCondition.farm_id = farm_id;
      }
      if (start_date && end_date) {
        whereCondition.alert_time = {
          [Op.between]: [new Date(start_date), new Date(end_date)]
        };
      }

      // 获取总预警数
      const totalAlerts = await DeviceAlert.count({
        where: whereCondition
      });

      // 按级别统计
      const alertsByLevel = await DeviceAlert.findAll({
        attributes: [
          'alert_level',
          [DeviceAlert.sequelize.fn('COUNT', DeviceAlert.sequelize.col('id')), 'count']
        ],
        where: whereCondition,
        group: ['alert_level'],
        raw: true
      });

      // 按状态统计
      const alertsByStatus = await DeviceAlert.findAll({
        attributes: [
          'status',
          [DeviceAlert.sequelize.fn('COUNT', DeviceAlert.sequelize.col('id')), 'count']
        ],
        where: whereCondition,
        group: ['status'],
        raw: true
      });

      // 按类型统计
      const alertsByType = await DeviceAlert.findAll({
        attributes: [
          'alert_type',
          [DeviceAlert.sequelize.fn('COUNT', DeviceAlert.sequelize.col('id')), 'count']
        ],
        where: whereCondition,
        group: ['alert_type'],
        raw: true
      });

      // 未读预警数
      const unreadAlerts = await DeviceAlert.count({
        where: {
          ...whereCondition,
          is_read: false
        }
      });

      // 今日新增预警
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const tomorrow = new Date(today);
      tomorrow.setDate(tomorrow.getDate() + 1);

      const todayAlerts = await DeviceAlert.count({
        where: {
          ...whereCondition,
          alert_time: {
            [Op.gte]: today,
            [Op.lt]: tomorrow
          }
        }
      });

      res.json({
        success: true,
        data: {
          total_alerts: totalAlerts,
          unread_alerts: unreadAlerts,
          today_alerts: todayAlerts,
          alerts_by_level: alertsByLevel,
          alerts_by_status: alertsByStatus,
          alerts_by_type: alertsByType
        }
      });

    } catch (error) {
      logger.error('获取预警统计失败:', error);
      res.status(500).json({
        success: false,
        message: '获取预警统计失败',
        error: error.message
      });
    }
  }

  /**
   * 获取预警列表
   */
  static async getAlertList(req, res) {
    try {
      const {
        page = 1,
        limit = 20,
        alert_level,
        status,
        alert_type,
        farm_id,
        start_date,
        end_date,
        is_read,
        device_code,
        keyword
      } = req.query;

      // 构建查询条件
      const whereCondition = {};
      if (alert_level) {
        whereCondition.alert_level = alert_level;
      }
      if (status) {
        whereCondition.status = status;
      }
      if (alert_type) {
        whereCondition.alert_type = alert_type;
      }
      if (farm_id) {
        whereCondition.farm_id = farm_id;
      }
      if (is_read !== undefined) {
        whereCondition.is_read = is_read === 'true';
      }
      if (start_date && end_date) {
        whereCondition.alert_time = {
          [Op.between]: [new Date(start_date), new Date(end_date)]
        };
      }
      if (keyword) {
        whereCondition[Op.or] = [
          { alert_title: { [Op.like]: `%${keyword}%` } },
          { alert_content: { [Op.like]: `%${keyword}%` } }
        ];
      }

      // 设备查询条件
      const deviceWhere = {};
      if (device_code) {
        deviceWhere.device_number = { [Op.like]: `%${device_code}%` };
      }

      const offset = (page - 1) * limit;

      const { count, rows } = await DeviceAlert.findAndCountAll({
        where: whereCondition,
        include: [
          {
            model: Device,
            as: 'device',
            where: Object.keys(deviceWhere).length > 0 ? deviceWhere : undefined,
            attributes: ['id', 'device_number', 'device_name', 'device_type', 'installation_location']
          },
          {
            model: User,
            as: 'handler',
            attributes: ['id', 'username', 'real_name'],
            required: false
          }
        ],
        order: [['alert_time', 'DESC']],
        limit: parseInt(limit),
        offset: offset
      });

      res.json({
        success: true,
        data: {
          alerts: rows,
          pagination: {
            current_page: parseInt(page),
            per_page: parseInt(limit),
            total: count,
            total_pages: Math.ceil(count / limit)
          }
        }
      });

    } catch (error) {
      logger.error('获取预警列表失败:', error);
      res.status(500).json({
        success: false,
        message: '获取预警列表失败',
        error: error.message
      });
    }
  }

  /**
   * 获取预警详情
   */
  static async getAlertDetail(req, res) {
    try {
      const { id } = req.params;

      const alert = await DeviceAlert.findByPk(id, {
        include: [
          {
            model: Device,
            as: 'device',
            attributes: ['id', 'device_number', 'device_name', 'device_type', 'device_model', 'manufacturer', 'installation_location']
          },
          {
            model: User,
            as: 'handler',
            attributes: ['id', 'username', 'real_name'],
            required: false
          }
        ]
      });

      if (!alert) {
        return res.status(404).json({
          success: false,
          message: '预警信息不存在'
        });
      }

      res.json({
        success: true,
        data: alert
      });

    } catch (error) {
      logger.error('获取预警详情失败:', error);
      res.status(500).json({
        success: false,
        message: '获取预警详情失败',
        error: error.message
      });
    }
  }

  /**
   * 标记预警为已读
   */
  static async markAsRead(req, res) {
    try {
      const { id } = req.params;
      const userId = req.user.id;

      const alert = await DeviceAlert.findByPk(id);
      if (!alert) {
        return res.status(404).json({
          success: false,
          message: '预警信息不存在'
        });
      }

      await alert.update({
        is_read: true,
        read_time: new Date()
      });

      res.json({
        success: true,
        message: '标记已读成功'
      });

    } catch (error) {
      logger.error('标记预警已读失败:', error);
      res.status(500).json({
        success: false,
        message: '标记预警已读失败',
        error: error.message
      });
    }
  }

  /**
   * 批量标记预警为已读
   */
  static async batchMarkAsRead(req, res) {
    try {
      const { alert_ids } = req.body;
      const userId = req.user.id;

      if (!alert_ids || !Array.isArray(alert_ids) || alert_ids.length === 0) {
        return res.status(400).json({
          success: false,
          message: '请提供有效的预警ID列表'
        });
      }

      await DeviceAlert.update(
        {
          is_read: true,
          read_time: new Date()
        },
        {
          where: {
            id: {
              [Op.in]: alert_ids
            }
          }
        }
      );

      res.json({
        success: true,
        message: '批量标记已读成功'
      });

    } catch (error) {
      logger.error('批量标记预警已读失败:', error);
      res.status(500).json({
        success: false,
        message: '批量标记预警已读失败',
        error: error.message
      });
    }
  }

  /**
   * 处理预警
   */
  static async handleAlert(req, res) {
    try {
      const { id } = req.params;
      const { status, handle_note } = req.body;
      const userId = req.user.id;

      const alert = await DeviceAlert.findByPk(id);
      if (!alert) {
        return res.status(404).json({
          success: false,
          message: '预警信息不存在'
        });
      }

      await alert.update({
        status,
        handler_id: userId,
        handle_time: new Date(),
        handle_note,
        is_read: true,
        read_time: alert.read_time || new Date()
      });

      res.json({
        success: true,
        message: '预警处理成功'
      });

    } catch (error) {
      logger.error('处理预警失败:', error);
      res.status(500).json({
        success: false,
        message: '处理预警失败',
        error: error.message
      });
    }
  }

  /**
   * 创建预警（系统内部使用）
   */
  static async createAlert(req, res) {
    try {
      const {
        device_id,
        alert_type,
        alert_level,
        alert_title,
        alert_content,
        farm_id,
        barn_id
      } = req.body;

      const alert = await DeviceAlert.create({
        device_id,
        alert_type,
        alert_level,
        alert_title,
        alert_content,
        farm_id,
        barn_id,
        alert_time: new Date()
      });

      res.json({
        success: true,
        message: '预警创建成功',
        data: alert
      });

    } catch (error) {
      logger.error('创建预警失败:', error);
      res.status(500).json({
        success: false,
        message: '创建预警失败',
        error: error.message
      });
    }
  }

  /**
   * 导出设备预警列表到Excel
   */
  static async exportToExcel(req, res) {
    try {
      const { alert_level, alert_type, status, is_read } = req.query;

      // 构建查询条件
      const where = {};
      if (alert_level) where.alert_level = alert_level;
      if (alert_type) where.alert_type = alert_type;
      if (status) where.status = status;
      if (is_read !== undefined) where.is_read = is_read === 'true';

      // 查询所有符合条件的数据
      const alerts = await DeviceAlert.findAll({
        where,
        include: [{
          model: Device,
          as: 'Device',
          attributes: ['device_name', 'device_number', 'installation_location']
        }],
        order: [['alert_time', 'DESC']],
        raw: true,
        nest: true
      });

      // 状态映射
      const levelMap = {
        info: '信息',
        warning: '警告',
        critical: '严重'
      };

      const typeMap = {
        temperature: '温度异常',
        humidity: '湿度异常',
        offline: '设备离线',
        maintenance: '设备维护'
      };

      const statusMap = {
        pending: '待处理',
        processing: '处理中',
        resolved: '已解决'
      };

      // 准备导出数据
      const exportData = alerts.map(alert => ({
        alert_title: alert.alert_title || '',
        alert_level: ExcelExport.formatStatus(alert.alert_level, levelMap),
        alert_type: ExcelExport.formatStatus(alert.alert_type, typeMap),
        alert_content: alert.alert_content || '',
        device_name: alert.Device?.device_name || '',
        device_number: alert.Device?.device_number || '',
        installation_location: alert.Device?.installation_location || '',
        status: ExcelExport.formatStatus(alert.status, statusMap),
        is_read: alert.is_read ? '已读' : '未读',
        alert_time: ExcelExport.formatDate(alert.alert_time),
        read_time: ExcelExport.formatDate(alert.read_time)
      }));

      // 定义列
      const columns = [
        { header: '预警标题', key: 'alert_title', width: 30 },
        { header: '预警级别', key: 'alert_level', width: 12 },
        { header: '预警类型', key: 'alert_type', width: 15 },
        { header: '预警内容', key: 'alert_content', width: 40 },
        { header: '设备名称', key: 'device_name', width: 20 },
        { header: '设备编号', key: 'device_number', width: 20 },
        { header: '安装位置', key: 'installation_location', width: 30 },
        { header: '处理状态', key: 'status', width: 12 },
        { header: '阅读状态', key: 'is_read', width: 10 },
        { header: '预警时间', key: 'alert_time', width: 20 },
        { header: '阅读时间', key: 'read_time', width: 20 }
      ];

      // 生成Excel
      const buffer = await ExcelExport.exportToExcel(exportData, columns, '设备预警列表');

      // 设置响应头
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', `attachment; filename=device_alerts_${Date.now()}.xlsx`);
      
      // 发送文件
      res.send(buffer);

    } catch (error) {
      logger.error('导出设备预警失败:', error);
      res.status(500).json({
        success: false,
        message: '导出失败',
        error: error.message
      });
    }
  }
}

module.exports = DeviceAlertController;