const { OperationLog, User } = require('../models');
const { Op } = require('sequelize');
const ExcelJS = require('exceljs');
const ExcelExport = require('../utils/excelExport');

/**
 * 操作日志控制器
 */
class OperationLogController {
  /**
   * 获取操作日志列表
   */
  async getOperationLogs(req, res) {
    try {
      const {
        page = 1,
        limit = 20,
        user_id,
        operation_type,
        operation_module,
        status,
        start_date,
        end_date,
        keyword
      } = req.query;

      // 构建查询条件
      const whereConditions = {};

      if (user_id) {
        whereConditions.user_id = user_id;
      }

      if (operation_type) {
        whereConditions.operation_type = operation_type;
      }

      if (operation_module) {
        whereConditions.operation_module = operation_module;
      }

      if (status) {
        whereConditions.status = status;
      }

      // 时间范围查询
      if (start_date || end_date) {
        whereConditions.created_at = {};
        if (start_date) {
          whereConditions.created_at[Op.gte] = new Date(start_date);
        }
        if (end_date) {
          const endDateTime = new Date(end_date);
          endDateTime.setHours(23, 59, 59, 999);
          whereConditions.created_at[Op.lte] = endDateTime;
        }
      }

      // 关键词搜索
      if (keyword) {
        whereConditions[Op.or] = [
          { operation_content: { [Op.like]: `%${keyword}%` } },
          { operation_target: { [Op.like]: `%${keyword}%` } },
          { request_url: { [Op.like]: `%${keyword}%` } },
          { ip_address: { [Op.like]: `%${keyword}%` } }
        ];
      }

      // 分页参数
      const offset = (parseInt(page) - 1) * parseInt(limit);

      // 查询操作日志
      const { count, rows } = await OperationLog.findAndCountAll({
        where: whereConditions,
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'username', 'real_name', 'email']
          }
        ],
        order: [['created_at', 'DESC']],
        limit: parseInt(limit),
        offset: offset
      });

      const totalPages = Math.ceil(count / parseInt(limit));

      res.json({
        status: 'success',
        message: '获取操作日志列表成功',
        data: {
          logs: rows,
          total: count,
          page: parseInt(page),
          limit: parseInt(limit),
          totalPages: totalPages
        }
      });
    } catch (error) {
      console.error('获取操作日志列表失败:', error);
      res.status(500).json({
        status: 'error',
        message: '获取操作日志列表失败',
        error: error.message
      });
    }
  }

  /**
   * 获取操作日志统计信息
   */
  async getOperationStats(req, res) {
    try {
      const {
        user_id,
        start_date,
        end_date
      } = req.query;

      // 构建查询条件
      const whereConditions = {};

      if (user_id) {
        whereConditions.user_id = user_id;
      }

      // 时间范围查询
      if (start_date || end_date) {
        whereConditions.created_at = {};
        if (start_date) {
          whereConditions.created_at[Op.gte] = new Date(start_date);
        }
        if (end_date) {
          const endDateTime = new Date(end_date);
          endDateTime.setHours(23, 59, 59, 999);
          whereConditions.created_at[Op.lte] = endDateTime;
        }
      }

      // 获取统计数据
      const stats = await OperationLog.getOperationStats(whereConditions);

      res.json({
        status: 'success',
        message: '获取操作日志统计成功',
        data: stats
      });
    } catch (error) {
      console.error('获取操作日志统计失败:', error);
      res.status(500).json({
        status: 'error',
        message: '获取操作日志统计失败',
        error: error.message
      });
    }
  }

  /**
   * 获取操作日志详情
   */
  async getOperationLogById(req, res) {
    try {
      const { id } = req.params;

      const log = await OperationLog.findByPk(id, {
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'username', 'real_name', 'email']
          }
        ]
      });

      if (!log) {
        return res.status(404).json({
          status: 'error',
          message: '操作日志不存在'
        });
      }

      res.json({
        status: 'success',
        message: '获取操作日志详情成功',
        data: log
      });
    } catch (error) {
      console.error('获取操作日志详情失败:', error);
      res.status(500).json({
        status: 'error',
        message: '获取操作日志详情失败',
        error: error.message
      });
    }
  }

  /**
   * 导出操作日志
   */
  async exportOperationLogs(req, res) {
    try {
      const {
        user_id,
        operation_type,
        operation_module,
        status,
        start_date,
        end_date,
        keyword
      } = req.body;

      // 构建查询条件
      const whereConditions = {};

      if (user_id) {
        whereConditions.user_id = user_id;
      }

      if (operation_type) {
        whereConditions.operation_type = operation_type;
      }

      if (operation_module) {
        whereConditions.operation_module = operation_module;
      }

      if (status) {
        whereConditions.status = status;
      }

      // 时间范围查询
      if (start_date || end_date) {
        whereConditions.created_at = {};
        if (start_date) {
          whereConditions.created_at[Op.gte] = new Date(start_date);
        }
        if (end_date) {
          const endDateTime = new Date(end_date);
          endDateTime.setHours(23, 59, 59, 999);
          whereConditions.created_at[Op.lte] = endDateTime;
        }
      }

      // 关键词搜索
      if (keyword) {
        whereConditions[Op.or] = [
          { operation_content: { [Op.like]: `%${keyword}%` } },
          { operation_target: { [Op.like]: `%${keyword}%` } },
          { request_url: { [Op.like]: `%${keyword}%` } },
          { ip_address: { [Op.like]: `%${keyword}%` } }
        ];
      }

      // 查询所有符合条件的日志
      const logs = await OperationLog.findAll({
        where: whereConditions,
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'username', 'real_name', 'email']
          }
        ],
        order: [['created_at', 'DESC']]
      });

      // 创建Excel工作簿
      const workbook = new ExcelJS.Workbook();
      const worksheet = workbook.addWorksheet('操作日志');

      // 设置表头
      worksheet.columns = [
        { header: 'ID', key: 'id', width: 10 },
        { header: '操作用户', key: 'username', width: 15 },
        { header: '真实姓名', key: 'real_name', width: 15 },
        { header: '操作类型', key: 'operation_type', width: 15 },
        { header: '操作模块', key: 'operation_module', width: 15 },
        { header: '操作内容', key: 'operation_content', width: 30 },
        { header: '操作目标', key: 'operation_target', width: 20 },
        { header: '请求方法', key: 'request_method', width: 10 },
        { header: '请求URL', key: 'request_url', width: 30 },
        { header: 'IP地址', key: 'ip_address', width: 15 },
        { header: '执行时间(ms)', key: 'execution_time', width: 12 },
        { header: '状态', key: 'status', width: 10 },
        { header: '错误信息', key: 'error_message', width: 30 },
        { header: '创建时间', key: 'created_at', width: 20 }
      ];

      // 添加数据
      logs.forEach(log => {
        worksheet.addRow({
          id: log.id,
          username: log.user ? log.user.username : '',
          real_name: log.user ? log.user.real_name : '',
          operation_type: log.operation_type,
          operation_module: log.operation_module,
          operation_content: log.operation_content,
          operation_target: log.operation_target,
          request_method: log.request_method,
          request_url: log.request_url,
          ip_address: log.ip_address,
          execution_time: log.execution_time,
          status: log.status,
          error_message: log.error_message,
          created_at: log.created_at
        });
      });

      // 设置响应头
      const filename = `操作日志_${new Date().toISOString().slice(0, 10)}.xlsx`;
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);

      // 写入响应
      await workbook.xlsx.write(res);
      res.end();

      // 记录导出操作日志
      await OperationLog.logOperation({
        user_id: req.user.id,
        operation_type: 'export',
        operation_module: 'operation_logs',
        operation_content: '导出操作日志',
        operation_target: `导出${logs.length}条记录`,
        request_method: 'POST',
        request_url: '/api/operation-logs/export',
        request_params: req.body,
        ip_address: req.ip,
        user_agent: req.get('User-Agent'),
        status: 'success'
      });

    } catch (error) {
      console.error('导出操作日志失败:', error);
      res.status(500).json({
        status: 'error',
        message: '导出操作日志失败',
        error: error.message
      });
    }
  }

  /**
   * 导出操作日志列表到Excel
   */
  async exportToExcel(req, res) {
    try {
      const { username, operation_type, operation_module, startDate, endDate } = req.query;

      // 构建查询条件
      const where = {};
      if (username) {
        where['$User.username$'] = { [Op.like]: `%${username}%` };
      }
      if (operation_type) where.operation_type = operation_type;
      if (operation_module) where.operation_module = operation_module;
      if (startDate && endDate) {
        where.created_at = {
          [Op.between]: [new Date(startDate), new Date(endDate)]
        };
      }

      // 查询所有符合条件的数据
      const logs = await OperationLog.findAll({
        where,
        include: [{
          model: User,
          as: 'User',
          attributes: ['username', 'real_name']
        }],
        order: [['created_at', 'DESC']],
        raw: true,
        nest: true
      });

      // 操作类型映射
      const typeMap = {
        login: '登录',
        logout: '登出',
        create: '创建',
        update: '更新',
        delete: '删除',
        view: '查看',
        export: '导出'
      };

      const statusMap = {
        success: '成功',
        failure: '失败'
      };

      // 准备导出数据
      const exportData = logs.map(log => ({
        username: log.User?.username || '',
        real_name: log.User?.real_name || '',
        operation_type: ExcelExport.formatStatus(log.operation_type, typeMap),
        operation_module: log.operation_module || '',
        operation_desc: log.operation_desc || '',
        ip_address: log.ip_address || '',
        status: ExcelExport.formatStatus(log.status, statusMap),
        created_at: ExcelExport.formatDate(log.created_at)
      }));

      // 定义列
      const columns = [
        { header: '用户名', key: 'username', width: 15 },
        { header: '真实姓名', key: 'real_name', width: 15 },
        { header: '操作类型', key: 'operation_type', width: 12 },
        { header: '操作模块', key: 'operation_module', width: 20 },
        { header: '操作描述', key: 'operation_desc', width: 40 },
        { header: 'IP地址', key: 'ip_address', width: 20 },
        { header: '状态', key: 'status', width: 10 },
        { header: '操作时间', key: 'created_at', 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=operation_logs_${Date.now()}.xlsx`);
      
      // 发送文件
      res.send(buffer);

    } catch (error) {
      console.error('导出操作日志失败:', error);
      res.status(500).json({
        status: 'error',
        message: '导出失败',
        error: error.message
      });
    }
  }
}

module.exports = new OperationLogController();