/**
 * 报表生成服务
 * @file reportService.js
 * @description 实现PDF报表生成和数据导出功能
 */
// const puppeteer = require('puppeteer'); // 暂时注释，避免模块缺失错误
const XLSX = require('xlsx');
const ejs = require('ejs');
const path = require('path');
const fs = require('fs');
const moment = require('moment');
const { Farm, Animal, Device, Alert, User, Product, Order, OrderItem } = require('../models');
const { Op, Sequelize } = require('sequelize');
const logger = require('../utils/logger');

// 设置中文本地化
moment.locale('zh-cn');

class ReportService {
  constructor() {
    this.templateDir = path.join(__dirname, '../templates');
    this.outputDir = path.join(__dirname, '../reports');
    this.ensureDirectories();
  }

  ensureDirectories() {
    if (!fs.existsSync(this.templateDir)) {
      fs.mkdirSync(this.templateDir, { recursive: true });
    }
    if (!fs.existsSync(this.outputDir)) {
      fs.mkdirSync(this.outputDir, { recursive: true });
    }
  }

  // 生成Excel报表
  async generateExcelReport(data, filename) {
    try {
      const workbook = XLSX.utils.book_new();
      
      // 添加农场数据
      if (data.farms && data.farms.length > 0) {
        const farmsSheet = XLSX.utils.json_to_sheet(data.farms);
        XLSX.utils.book_append_sheet(workbook, farmsSheet, '农场数据');
      }
      
      // 添加动物数据
      if (data.animals && data.animals.length > 0) {
        const animalsSheet = XLSX.utils.json_to_sheet(data.animals);
        XLSX.utils.book_append_sheet(workbook, animalsSheet, '动物数据');
      }
      
      // 添加设备数据
      if (data.devices && data.devices.length > 0) {
        const devicesSheet = XLSX.utils.json_to_sheet(data.devices);
        XLSX.utils.book_append_sheet(workbook, devicesSheet, '设备数据');
      }

      // 添加告警数据
      if (data.alerts && data.alerts.length > 0) {
        const alertsSheet = XLSX.utils.json_to_sheet(data.alerts);
        XLSX.utils.book_append_sheet(workbook, alertsSheet, '告警数据');
      }

      // 添加订单数据
      if (data.orders && data.orders.length > 0) {
        const ordersSheet = XLSX.utils.json_to_sheet(data.orders);
        XLSX.utils.book_append_sheet(workbook, ordersSheet, '订单数据');
      }

      const filePath = path.join(this.outputDir, filename);
      XLSX.writeFile(workbook, filePath);
      
      logger.info(`Excel报表生成成功: ${filePath}`, { service: 'reportService' });
      return filePath;
    } catch (error) {
      logger.error('Excel报表生成失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // PDF生成功能暂时禁用
  async generatePDFReport(data, filename) {
    logger.warn('PDF报表功能暂时不可用，puppeteer模块未安装', { service: 'reportService' });
    throw new Error('PDF报表功能暂时不可用，请使用Excel格式或联系管理员安装puppeteer模块');
  }

  // HTML转PDF功能暂时禁用
  async generatePDFFromHTML(htmlContent, filename) {
    logger.warn('PDF生成功能暂时不可用，puppeteer模块未安装', { service: 'reportService' });
    throw new Error('PDF生成功能暂时不可用，请使用Excel格式或联系管理员安装puppeteer模块');
  }

  // 获取农场统计数据
  async getFarmStatistics(farmId = null) {
    try {
      const whereClause = farmId ? { id: farmId } : {};
      
      const farms = await Farm.findAll({
        where: whereClause,
        include: [
          {
            model: Animal,
            as: 'animals',
            required: false
          },
          {
            model: Device,
            as: 'devices',
            required: false
          }
        ]
      });

      return farms;
    } catch (error) {
      logger.error('获取农场统计数据失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 获取动物统计数据
  async getAnimalStatistics(farmId = null) {
    try {
      const whereClause = farmId ? { farmId } : {};
      
      const animals = await Animal.findAll({
        where: whereClause,
        include: [
          {
            model: Farm,
            as: 'farm',
            attributes: ['name', 'location']
          }
        ]
      });

      return animals;
    } catch (error) {
      logger.error('获取动物统计数据失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 获取设备统计数据
  async getDeviceStatistics(farmId = null) {
    try {
      const whereClause = farmId ? { farmId } : {};
      
      const devices = await Device.findAll({
        where: whereClause,
        include: [
          {
            model: Farm,
            as: 'farm',
            attributes: ['name', 'location']
          }
        ]
      });

      return devices;
    } catch (error) {
      logger.error('获取设备统计数据失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 获取告警统计数据
  async getAlertStatistics(farmId = null) {
    try {
      const whereClause = farmId ? { farmId } : {};
      
      const alerts = await Alert.findAll({
        where: whereClause,
        include: [
          {
            model: Farm,
            as: 'farm',
            attributes: ['name', 'location']
          }
        ]
      });

      return alerts;
    } catch (error) {
      logger.error('获取告警统计数据失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 获取订单统计数据
  async getOrderStatistics(farmId = null) {
    try {
      const whereClause = farmId ? { farmId } : {};
      
      const orders = await Order.findAll({
        where: whereClause,
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['username', 'email']
          },
          {
            model: OrderItem,
            as: 'items',
            include: [
              {
                model: Product,
                as: 'product',
                attributes: ['name', 'price']
              }
            ]
          }
        ]
      });

      return orders;
    } catch (error) {
      logger.error('获取订单统计数据失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 生成综合报表
  async generateComprehensiveReport(farmId = null, format = 'excel') {
    try {
      const data = {
        farms: await this.getFarmStatistics(farmId),
        animals: await this.getAnimalStatistics(farmId),
        devices: await this.getDeviceStatistics(farmId),
        alerts: await this.getAlertStatistics(farmId),
        orders: await this.getOrderStatistics(farmId)
      };

      const timestamp = moment().format('YYYY-MM-DD_HH-mm-ss');
      const filename = `comprehensive_report_${timestamp}.${format}`;

      if (format === 'excel') {
        return await this.generateExcelReport(data, filename);
      } else if (format === 'pdf') {
        return await this.generatePDFReport(data, filename);
      } else {
        throw new Error('不支持的报表格式');
      }
    } catch (error) {
      logger.error('生成综合报表失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 清理过期报表文件
  async cleanupOldReports(daysOld = 7) {
    try {
      const files = fs.readdirSync(this.outputDir);
      const cutoffTime = Date.now() - (daysOld * 24 * 60 * 60 * 1000);
      
      let cleanedCount = 0;
      files.forEach(file => {
        const filePath = path.join(this.outputDir, file);
        const stats = fs.statSync(filePath);
        
        if (stats.mtime.getTime() < cutoffTime) {
          fs.unlinkSync(filePath);
          cleanedCount++;
        }
      });
      
      logger.info(`清理了 ${cleanedCount} 个过期报表文件`, { service: 'reportService' });
      return cleanedCount;
    } catch (error) {
      logger.error('清理过期报表文件失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 获取报表文件列表
  async getReportFiles() {
    try {
      const files = fs.readdirSync(this.outputDir);
      const fileList = files.map(file => {
        const filePath = path.join(this.outputDir, file);
        const stats = fs.statSync(filePath);
        return {
          filename: file,
          size: stats.size,
          created: stats.birthtime,
          modified: stats.mtime
        };
      });

      return fileList.sort((a, b) => b.modified - a.modified);
    } catch (error) {
      logger.error('获取报表文件列表失败:', error, { service: 'reportService' });
      throw error;
    }
  }

  // 删除报表文件
  async deleteReportFile(filename) {
    try {
      const filePath = path.join(this.outputDir, filename);
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
        logger.info(`报表文件删除成功: ${filename}`, { service: 'reportService' });
        return true;
      } else {
        throw new Error('文件不存在');
      }
    } catch (error) {
      logger.error('删除报表文件失败:', error, { service: 'reportService' });
      throw error;
    }
  }
}

module.exports = new ReportService();
