package com.jiayue.ipfcst.controller;

import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
import com.jiayue.ipfcst.common.data.entity.DisplayConfig;
import com.jiayue.ipfcst.common.data.entity.ElectricField;
import com.jiayue.ipfcst.service.DisplayConfigService;
import com.jiayue.ipfcst.service.ElectricFieldService;
import com.jiayue.ipfcst.service.RealTimeComprehensiveContrastOneService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

/**
 * 实时对比查询restful接口
 *
 * @author tl
 * @version 1.0
 * @since 2019/8/7 10:12
 */
@RestController
@Slf4j
public class RealTimeComprehensiveContrastOneController {
  private final DisplayConfigService displayConfigService;
  private final RealTimeComprehensiveContrastOneService realTimeComprehensiveContrastOneService;
  private final ElectricFieldService electricFieldService;

  @Autowired
  public RealTimeComprehensiveContrastOneController(DisplayConfigService displayConfigService,
                                                    RealTimeComprehensiveContrastOneService realTimeComprehensiveContrastOneService,
                                                    ElectricFieldService electricFieldService) {


    this.displayConfigService = displayConfigService;
    this.realTimeComprehensiveContrastOneService = realTimeComprehensiveContrastOneService;
    this.electricFieldService = electricFieldService;
  }

  /**
   * 综合数据对比查询
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return
   */
  @GetMapping(value = "realTimeComprehensiveContrastOne/{startTime}/{endTime}/{jgTime}")
  public ResponseVO realTimeComprehensiveQueryForcharts(@PathVariable("startTime") Long startTime,
                                                        @PathVariable("endTime") Long endTime,
                                                        @PathVariable("jgTime") Long jgTime

  ) throws Exception {
    return ResponseVO.success(realTimeComprehensiveContrastOneService.realTimeComprehensiveContrast(startTime, endTime, jgTime));
  }


  /**
   * 综合数据对比查询
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return
   */
  @GetMapping(value = "realTimeComprehensiveContrastOneExport/{startTime}/{endTime}/{jgTime}")
  public ResponseVO export(@PathVariable("startTime") Long startTime,
                           @PathVariable("endTime") Long endTime,
                           @PathVariable("jgTime") Long jgTime,
                           HttpServletResponse response

  ) throws Exception {

    Map<String, Object> map = realTimeComprehensiveContrastOneService.realTimeComprehensiveContrast(startTime, endTime, jgTime);

    BufferedOutputStream bos = null;
    try {
      StringBuilder templateContent = new StringBuilder();
      response.setCharacterEncoding("UTF-8");
      ElectricField electricField = electricFieldService.get();
      DisplayConfig displayConfig = null;
      displayConfig = displayConfigService.findByDisplayCode("rtWindTowerInfos");
      String showCode = displayConfig.getShowCode();
      String[] split = showCode.split(",");
      String header = "\"时间\",";
      for (int i = 0; i < split.length; i++) {
        switch (split[i]) {
          case "realValue":
            header += "\"实际功率\",";
            break;
          case "rDq":
            header += "\"实时短期\",";
            break;
        }
      }
      header += "\r\n";
      List<Map<String, Float>> tableResult = (List<Map<String, Float>>) map.get("tableResult");
      List<Map<String, Float>> resultList = (List<Map<String, Float>>) map.get("resultList");

      templateContent.append(header);
      for (int i = 0; i < tableResult.size(); i++) {
        StringBuilder content = new StringBuilder();

        content.append(tableResult.get(i).get("time") + ",");

        for (int n = 0; n < split.length; n++) {
          switch (split[n]) {
            case "realValue":
              content.append(tableResult.get(i).get("realValue") + ",");
              break;
            case "rDq":
              content.append(tableResult.get(i).get("rDq") + ",");
              break;
          }
        }
        content.append("\r\n");
        templateContent.append(content.toString());
      }

      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

      response.setContentType("application/x-msdownload;charset=UTF-8");// 文件下载必须配置为application/x-msdownload
      response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(sdf.format(startTime) + "至" + sdf.format(endTime) + "实时预测查询导出文件" + ".csv", "UTF-8"));// 中文文件名必须使用URLEncoder.encode进行转码
      byte[] templateContentBytes = templateContent.toString().getBytes("UTF-8");
      bos = new BufferedOutputStream(response.getOutputStream());// 向response中写入文件流
      bos.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});// 指定csv文件用UTF-8字符集打开
      bos.write(templateContentBytes);
      response.flushBuffer();
      templateContent = null;

    } catch (Exception e) {
      log.error("系统错误：" + e.getMessage(), e);
      throw new RuntimeException(e);
    } finally {
      if (bos != null) {
        try {
          bos.close();
        } catch (IOException e) {
          log.error("系统错误：" + e.getMessage(), e);
        }
      }
    }


    return ResponseVO.success();
  }

  @PostMapping(value = "/ComprehensiveContrastOneExports")
  public ResponseVO exportExcelForImg(Long startTime,
                                      Long endTime,
                                      Long jgTime,
                                      String base64) throws Exception {
    //创建Excel工作簿，xls格式用HSSFWorkbook，xlsx格式用SXSSFWorkbook
    HSSFWorkbook wb = new HSSFWorkbook();
    //创建sheet页
    HSSFSheet sheet = wb.createSheet();
    //创建绘图(画布)，注明：一个sheet只能创建一个画布，但一个画布中可以添加多张图片
    HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
    String fileContent;
    // 图片编码只要‘base64,’后面的部分
    fileContent = URLDecoder.decode(base64, "UTF-8").substring(22);

    //#########################插入数据#########################
    Map<String, Object> map = realTimeComprehensiveContrastOneService.realTimeComprehensiveContrast(startTime, endTime, jgTime);
    BufferedOutputStream bos = null;
    StringBuilder templateContent = new StringBuilder();
    ElectricField electricField = electricFieldService.get();
    DisplayConfig displayConfig = null;
    displayConfig = displayConfigService.findByDisplayCode("rtWindTowerInfos");
    String showCode = displayConfig.getShowCode();
    String[] split = showCode.split(",");
    //创建第一行 0为第一行
    HSSFRow row1 = sheet.createRow(0);
    //设置第一个单元格
    row1.createCell(0).setCellValue("时间");
    int flag = 1;
    String displayKyLl = (String) map.get("displayKyLl");

    for (int i = 0; i < split.length; i++) {
      switch (split[i]) {
        case "realValue":
          row1.createCell(flag).setCellValue("实际功率");
          flag++;
          break;
        case "rDq":
          row1.createCell(flag).setCellValue("实时短期");
          flag++;
          break;
      }
    }
    List<Map<String, Float>> tableResult = (List<Map<String, Float>>) map.get("tableResult");
    List<Map<String, Float>> resultList = (List<Map<String, Float>>) map.get("resultList");

    for (int i = 0; i < tableResult.size(); i++) {
      int flags = 0;
      HSSFRow row = sheet.createRow(i + 1);
      row.createCell(flags).setCellValue(String.valueOf(tableResult.get(i).get("time")));
      flags++;
      for (int n = 0; n < split.length; n++) {
        switch (split[n]) {
          case "realValue":
            row.createCell(flags).setCellValue(String.valueOf(tableResult.get(i).get("realValue")));
            flags++;
            break;

          case "rDq":
            row.createCell(flags).setCellValue(String.valueOf(tableResult.get(i).get("rDq")));
            flags++;
            break;
        }
      }
    }

    //画图
    createPictureInExcel(fileContent, patriarch, wb);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String filename = sdf.format(startTime) + "至" + sdf.format(endTime) + "实时预测查询导出文件" + ".xls";
    File filepath = new File("/home/syjy/ipfcstV3/reportForm/");
    File file = new File("/home/syjy/ipfcstV3/reportForm/", filename);
    //File file = new File("/Users/wanghongchen/"+filename);
    if (!filepath.exists()) {
      filepath.mkdir();
    }
    if (!file.exists()) {
      file.createNewFile();
    }
    OutputStream out = new FileOutputStream(file);
    wb.write(out);
    wb.close();
    return ResponseVO.success(filename);
    //将文件生成到本地 读取本地文件调用浏览器下载
  }

  public static void createPictureInExcel(String dataChart, HSSFPatriarch patriarch, HSSFWorkbook wb) throws Exception {
    //用于将BASE64编码格式转为byte数组
    BASE64Decoder base64Decoder = new BASE64Decoder();
    ByteArrayOutputStream dataChartoutStream = new ByteArrayOutputStream();
    //将dataChartStringin作为输入流，读取图片存入image中
    ByteArrayInputStream dataChartin = new ByteArrayInputStream(base64Decoder.decodeBuffer(dataChart));

    BufferedImage dataChartbufferImg = ImageIO.read(dataChartin);
    //利用HSSFPatriarch将图片写入EXCEL
    ImageIO.write(dataChartbufferImg, "png", dataChartoutStream);
    /*
     * 指定绘图区域位置及大小
     * HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)
     * 参数说明：
     * dx1 dy1 起始单元格中的x,y坐标.
     * dx2 dy2 结束单元格中的x,y坐标.
     * col1,row1 指定起始的单元格，下标从0开始.
     * col2,row2 指定结束的单元格 ，下标从0开始.
     */
    HSSFClientAnchor anchorCostStr = new HSSFClientAnchor(10, 10, 255, 255, (short) 10, 10, (short) 20, 28);
    //画图
    patriarch.createPicture(anchorCostStr, wb.addPicture(dataChartoutStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
  }

  /**
   * 文件下载
   *
   * @param request  HttpServletRequest
   * @param response HttpServletResponse
   * @param path     路径
   * @param name     文件名
   * @param type     文件类型
   */
  @PostMapping(value = "/downLoadFileOne")
  public void downLoadFile(HttpServletRequest request,
                           HttpServletResponse response,
                           String path,
                           String name,
                           String type) {
    response.setContentType("text/html;charset=utf-8");
    try {
      request.setCharacterEncoding("UTF-8");
    } catch (UnsupportedEncodingException e1) {
      log.error("系统错误：" + e1.getMessage(), e1);
    }

    String downLoadPath = path + File.separator + name;
    if (name.isEmpty()) {//传入name为空，说明是一级目录，路径中已经包涵最后一级目录
      name = path.substring(path.lastIndexOf(File.separator) + 1, path.length());
      downLoadPath = path;
    }
    try {
      File df = new File(downLoadPath);
      InputStream ins = new FileInputStream(df);
      BufferedInputStream bins = new BufferedInputStream(ins);
      OutputStream outs = response.getOutputStream();
      BufferedOutputStream bouts = new BufferedOutputStream(outs);
      response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
      response.setContentType("application/x-msdownload; charset=utf-8");
      int bytesRead = 0;
      byte[] buffer = new byte[8192];
      while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
        bouts.write(buffer, 0, bytesRead);
      }
      bouts.flush();
      ins.close();
      bins.close();
      bouts.close();
      File deleteFile = new File(downLoadPath);
      deleteFile.delete();
    } catch (Exception e) {
      log.error("系统错误：" + e.getMessage(), e);
    }
  }
}
