/**
 * 报表管理路由
 * @file reports.js
 * @description 处理报表生成、下载和管理请求
 */
const express = require('express');
const { verifyToken, checkRole } = require('../middleware/auth');
const reportService = require('../services/reportService');
const logger = require('../utils/logger');
const path = require('path');
const fs = require('fs');

const router = express.Router();

/**
 * @swagger
 * tags:
 *   name: Reports
 *   description: 报表管理相关接口
 */

/**
 * @swagger
 * /api/reports/farm:
 *   post:
 *     summary: 生成养殖统计报表
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: false
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               startDate:
 *                 type: string
 *                 format: date
 *                 description: 开始日期
 *               endDate:
 *                 type: string
 *                 format: date
 *                 description: 结束日期
 *               farmIds:
 *                 type: array
 *                 items:
 *                   type: integer
 *                 description: 农场ID列表
 *               format:
 *                 type: string
 *                 enum: [pdf, excel, csv]
 *                 description: 报表格式
 *     responses:
 *       200:
 *         description: 报表生成成功
 *       401:
 *         description: 未授权
 *       500:
 *         description: 服务器错误
 */
router.post('/farm', verifyToken, async (req, res) => {
  try {
    const options = {
      startDate: req.body.startDate,
      endDate: req.body.endDate,
      farmIds: req.body.farmIds || [],
      format: req.body.format || 'pdf'
    };

    logger.info(`用户 ${req.user.username} 请求生成养殖统计报表`, options);

    const result = await reportService.generateFarmReport(options);
    
    res.json({
      success: true,
      message: '报表生成成功',
      data: {
        fileName: result.fileName,
        downloadUrl: `/api/reports/download/${encodeURIComponent(result.fileName)}`,
        mimeType: result.mimeType,
        size: result.size,
        generatedAt: new Date()
      }
    });
  } catch (error) {
    logger.error('生成养殖统计报表失败:', error);
    res.status(500).json({
      success: false,
      message: '报表生成失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/sales:
 *   post:
 *     summary: 生成销售分析报表
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: false
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               startDate:
 *                 type: string
 *                 format: date
 *                 description: 开始日期
 *               endDate:
 *                 type: string
 *                 format: date
 *                 description: 结束日期
 *               format:
 *                 type: string
 *                 enum: [pdf, excel]
 *                 description: 报表格式
 *     responses:
 *       200:
 *         description: 报表生成成功
 *       401:
 *         description: 未授权
 *       500:
 *         description: 服务器错误
 */
router.post('/sales', verifyToken, checkRole(['admin', 'manager']), async (req, res) => {
  try {
    const options = {
      startDate: req.body.startDate,
      endDate: req.body.endDate,
      format: req.body.format || 'pdf'
    };

    logger.info(`用户 ${req.user.username} 请求生成销售分析报表`, options);

    const result = await reportService.generateSalesReport(options);
    
    res.json({
      success: true,
      message: '销售分析报表生成成功',
      data: {
        fileName: result.fileName,
        downloadUrl: `/api/reports/download/${encodeURIComponent(result.fileName)}`,
        mimeType: result.mimeType,
        size: result.size,
        generatedAt: new Date()
      }
    });
  } catch (error) {
    logger.error('生成销售分析报表失败:', error);
    res.status(500).json({
      success: false,
      message: '销售分析报表生成失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/compliance:
 *   post:
 *     summary: 生成监管合规报表
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: false
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               startDate:
 *                 type: string
 *                 format: date
 *                 description: 开始日期
 *               endDate:
 *                 type: string
 *                 format: date
 *                 description: 结束日期
 *               format:
 *                 type: string
 *                 enum: [pdf, excel]
 *                 description: 报表格式
 *     responses:
 *       200:
 *         description: 报表生成成功
 *       401:
 *         description: 未授权
 *       403:
 *         description: 权限不足
 *       500:
 *         description: 服务器错误
 */
router.post('/compliance', verifyToken, checkRole(['admin']), async (req, res) => {
  try {
    const options = {
      startDate: req.body.startDate,
      endDate: req.body.endDate,
      format: req.body.format || 'pdf'
    };

    logger.info(`管理员 ${req.user.username} 请求生成监管合规报表`, options);

    const result = await reportService.generateComplianceReport(options);
    
    res.json({
      success: true,
      message: '监管合规报表生成成功',
      data: {
        fileName: result.fileName,
        downloadUrl: `/api/reports/download/${encodeURIComponent(result.fileName)}`,
        mimeType: result.mimeType,
        size: result.size,
        generatedAt: new Date()
      }
    });
  } catch (error) {
    logger.error('生成监管合规报表失败:', error);
    res.status(500).json({
      success: false,
      message: '监管合规报表生成失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/download/{fileName}:
 *   get:
 *     summary: 下载报表文件
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: fileName
 *         required: true
 *         schema:
 *           type: string
 *         description: 文件名
 *     responses:
 *       200:
 *         description: 文件下载成功
 *         content:
 *           application/pdf:
 *             schema:
 *               type: string
 *               format: binary
 *           application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
 *             schema:
 *               type: string
 *               format: binary
 *       404:
 *         description: 文件不存在
 *       401:
 *         description: 未授权
 */
router.get('/download/:fileName', verifyToken, async (req, res) => {
  try {
    const fileName = decodeURIComponent(req.params.fileName);
    const filePath = path.join(reportService.reportsPath, fileName);
    
    // 安全检查：确保文件在报表目录内
    if (!filePath.startsWith(reportService.reportsPath)) {
      logger.warn(`用户 ${req.user.username} 尝试访问非法路径: ${fileName}`);
      return res.status(403).json({
        success: false,
        message: '非法文件路径'
      });
    }

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      logger.warn(`文件不存在: ${fileName}`);
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    // 设置响应头
    const stat = fs.statSync(filePath);
    const ext = path.extname(fileName).toLowerCase();
    
    let mimeType = 'application/octet-stream';
    if (ext === '.pdf') {
      mimeType = 'application/pdf';
    } else if (ext === '.xlsx') {
      mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    } else if (ext === '.csv') {
      mimeType = 'text/csv';
    }

    res.setHeader('Content-Type', mimeType);
    res.setHeader('Content-Length', stat.size);
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(fileName)}"`);

    // 创建文件流并发送
    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(res);

    logger.info(`用户 ${req.user.username} 下载报表文件: ${fileName}`);
  } catch (error) {
    logger.error('下载报表文件失败:', error);
    res.status(500).json({
      success: false,
      message: '文件下载失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/list:
 *   get:
 *     summary: 获取报表文件列表
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: 获取成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       fileName:
 *                         type: string
 *                       size:
 *                         type: number
 *                       createdAt:
 *                         type: string
 *                       downloadUrl:
 *                         type: string
 */
router.get('/list', verifyToken, async (req, res) => {
  try {
    const files = fs.readdirSync(reportService.reportsPath);
    const fileList = [];

    for (const file of files) {
      const filePath = path.join(reportService.reportsPath, file);
      const stat = fs.statSync(filePath);
      
      fileList.push({
        fileName: file,
        size: stat.size,
        createdAt: stat.mtime,
        downloadUrl: `/api/reports/download/${encodeURIComponent(file)}`,
        mimeType: this.getMimeType(file)
      });
    }

    // 按创建时间降序排列
    fileList.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

    res.json({
      success: true,
      data: fileList,
      total: fileList.length
    });
  } catch (error) {
    logger.error('获取报表文件列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取报表文件列表失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/cleanup:
 *   post:
 *     summary: 清理过期报表文件
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: false
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               daysToKeep:
 *                 type: integer
 *                 description: 保留天数
 *                 default: 30
 *     responses:
 *       200:
 *         description: 清理成功
 *       401:
 *         description: 未授权
 *       403:
 *         description: 权限不足
 */
router.post('/cleanup', verifyToken, checkRole(['admin']), async (req, res) => {
  try {
    const daysToKeep = req.body.daysToKeep || 30;
    const deletedCount = await reportService.cleanupOldReports(daysToKeep);
    
    logger.info(`管理员 ${req.user.username} 执行报表清理，删除了 ${deletedCount} 个文件`);
    
    res.json({
      success: true,
      message: `清理完成，删除了 ${deletedCount} 个过期报表文件`,
      data: {
        deletedCount,
        daysToKeep
      }
    });
  } catch (error) {
    logger.error('清理过期报表失败:', error);
    res.status(500).json({
      success: false,
      message: '清理过期报表失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/export/farms:
 *   get:
 *     summary: 导出农场数据（Excel/CSV）
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: format
 *         schema:
 *           type: string
 *           enum: [excel, csv]
 *         description: 导出格式
 *     responses:
 *       200:
 *         description: 导出成功
 */
router.get('/export/farms', verifyToken, async (req, res) => {
  try {
    const format = req.query.format || 'excel';
    
    logger.info(`用户 ${req.user.username} 请求导出农场数据，格式: ${format}`);

    const result = await reportService.generateFarmReport({ format });
    
    // 直接发送文件
    const filePath = result.filePath;
    
    res.setHeader('Content-Type', result.mimeType);
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(result.fileName)}"`);
    
    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(res);
    
    // 异步删除临时文件
    setTimeout(() => {
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }, 60000); // 1分钟后删除
    
  } catch (error) {
    logger.error('导出农场数据失败:', error);
    res.status(500).json({
      success: false,
      message: '数据导出失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/export/devices:
 *   get:
 *     summary: 导出设备数据（Excel/CSV）
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: format
 *         schema:
 *           type: string
 *           enum: [excel, csv]
 *         description: 导出格式
 *       - in: query
 *         name: status
 *         schema:
 *           type: string
 *           enum: [online, offline, maintenance]
 *         description: 设备状态筛选
 *     responses:
 *       200:
 *         description: 导出成功
 */
router.get('/export/devices', verifyToken, async (req, res) => {
  try {
    const format = req.query.format || 'excel';
    const status = req.query.status;
    
    logger.info(`用户 ${req.user.username} 请求导出设备数据，格式: ${format}, 状态: ${status || '全部'}`);

    const result = await this.exportDevicesData(format, status);
    
    res.setHeader('Content-Type', result.mimeType);
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(result.fileName)}"`);
    
    const fileStream = fs.createReadStream(result.filePath);
    fileStream.pipe(res);
    
    // 异步删除临时文件
    setTimeout(() => {
      if (fs.existsSync(result.filePath)) {
        fs.unlinkSync(result.filePath);
      }
    }, 60000);
    
  } catch (error) {
    logger.error('导出设备数据失败:', error);
    res.status(500).json({
      success: false,
      message: '设备数据导出失败',
      error: error.message
    });
  }
});

/**
 * @swagger
 * /api/reports/templates:
 *   get:
 *     summary: 获取可用报表模板
 *     tags: [Reports]
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: 获取成功
 */
router.get('/templates', verifyToken, async (req, res) => {
  try {
    const templates = [
      {
        id: 'farm-statistics',
        name: '养殖统计报表',
        description: '包含农场、动物、设备和预警的综合统计',
        formats: ['pdf', 'excel', 'csv'],
        requiredParams: ['startDate', 'endDate'],
        optionalParams: ['farmIds']
      },
      {
        id: 'sales-analysis',
        name: '销售分析报表',
        description: '销售订单和产品销量分析报表',
        formats: ['pdf', 'excel'],
        requiredParams: ['startDate', 'endDate'],
        optionalParams: []
      },
      {
        id: 'compliance-check',
        name: '监管合规报表',
        description: '监管要求合规性检查报表',
        formats: ['pdf', 'excel'],
        requiredParams: ['startDate', 'endDate'],
        optionalParams: [],
        permissions: ['admin']
      }
    ];

    res.json({
      success: true,
      data: templates,
      total: templates.length
    });
  } catch (error) {
    logger.error('获取报表模板失败:', error);
    res.status(500).json({
      success: false,
      message: '获取报表模板失败',
      error: error.message
    });
  }
});

/**
 * 导出设备数据
 * @param {string} format 导出格式
 * @param {string} status 设备状态筛选
 * @returns {Object} 文件信息
 */
async function exportDevicesData(format, status) {
  try {
    const whereClause = {};
    if (status) {
      whereClause.status = status;
    }

    const devices = await Device.findAll({
      where: whereClause,
      include: [{
        model: Farm,
        as: 'farm',
        attributes: ['id', 'name']
      }],
      order: [['updated_at', 'DESC']]
    });

    if (format === 'excel') {
      const workbook = XLSX.utils.book_new();
      
      const deviceData = [
        ['设备ID', '设备名称', '设备类型', '设备状态', '所属农场', '安装日期', '最后维护', '创建时间', '更新时间']
      ];
      
      devices.forEach(device => {
        deviceData.push([
          device.id,
          device.name,
          device.type,
          device.status,
          device.farm?.name || '未知农场',
          device.installation_date ? moment(device.installation_date).format('YYYY-MM-DD') : '',
          device.last_maintenance ? moment(device.last_maintenance).format('YYYY-MM-DD') : '',
          moment(device.created_at).format('YYYY-MM-DD HH:mm:ss'),
          moment(device.updated_at).format('YYYY-MM-DD HH:mm:ss')
        ]);
      });
      
      const worksheet = XLSX.utils.aoa_to_sheet(deviceData);
      XLSX.utils.book_append_sheet(workbook, worksheet, '设备数据');
      
      const fileName = `设备数据导出_${moment().format('YYYYMMDD_HHmmss')}.xlsx`;
      const filePath = path.join(reportService.reportsPath, fileName);
      
      XLSX.writeFile(workbook, filePath);
      
      return {
        fileName,
        filePath,
        mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        size: fs.statSync(filePath).size
      };
    }
  } catch (error) {
    logger.error('导出设备数据失败:', error);
    throw error;
  }
}

/**
 * 获取文件MIME类型
 * @param {string} fileName 文件名
 * @returns {string} MIME类型
 */
function getMimeType(fileName) {
  const ext = path.extname(fileName).toLowerCase();
  const mimeTypes = {
    '.pdf': 'application/pdf',
    '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    '.csv': 'text/csv'
  };
  return mimeTypes[ext] || 'application/octet-stream';
}

module.exports = router;
