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.common.data.entity.SysParameter;
import com.jiayue.ipfcst.common.data.repository.SysParameterRepository;
import com.jiayue.ipfcst.service.ComprehensiveContrastService;
import com.jiayue.ipfcst.service.DisplayConfigService;
import com.jiayue.ipfcst.service.ElectricFieldService;
import lombok.extern.slf4j.Slf4j;
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.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 上报对比查询restful接口
 *
 * @author yh
 * @version 1.0
 * @since 2019/8/7 10:12
 */
@RestController
@Slf4j
public class ComprehensiveContrastController {
  private final ComprehensiveContrastService comprehensiveContrastService;
  private final DisplayConfigService displayConfigService;
  private final SysParameterRepository sysParameterRepository;
  private final ElectricFieldService electricFieldService;

  @Autowired
  public ComprehensiveContrastController(DisplayConfigService displayConfigService,
                                         SysParameterRepository sysParameterRepository,
                                         ComprehensiveContrastService comprehensiveContrastService,
                                         ElectricFieldService electricFieldService) {
    this.displayConfigService = displayConfigService;
    this.sysParameterRepository = sysParameterRepository;
    this.comprehensiveContrastService = comprehensiveContrastService;
    this.electricFieldService = electricFieldService;

  }

  /**
   * 综合数据对比查询
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param no
   * @return
   */
  @GetMapping(value = "comprehensiveContrast/{startTime}/{endTime}/{no}/{otherType}/{dqAgo}/{cdqAgo}/{nwpAgo}/{jgTime}")
  public ResponseVO comprehensiveQueryForcharts(@PathVariable("startTime") Long startTime,
                                                @PathVariable("endTime") Long endTime,
                                                @PathVariable("no") Integer no,
                                                @PathVariable("otherType") String otherType,
                                                @PathVariable("dqAgo") Integer dqAgo,
                                                @PathVariable("cdqAgo") Integer cdqAgo,
                                                @PathVariable("nwpAgo") Integer nwpAgo,
                                                @PathVariable("jgTime") Long jgTime

  ) throws Exception {
    return ResponseVO.success(comprehensiveContrastService.comprehensiveContrast(startTime, endTime, no, otherType, dqAgo, cdqAgo, nwpAgo, jgTime));
  }

  @GetMapping("/comprehensiveContrast/getSpeedColumn")
  public ResponseVO getSpeedColumn() {

    SysParameter sysParameter = sysParameterRepository.findBySysKeyEquals("NWP_CHANGE_WIND");
    Map<String, String> map = new HashMap<>();
    if (sysParameter != null) {

      String nwpChangeWind = sysParameter.getSysValue();
      String[] windChangeName = nwpChangeWind.split(",");
      if (windChangeName.length == 16) {

        map.put("ws10", "nwp" + windChangeName[0] + "米风速");
        map.put("ws30", "nwp" + windChangeName[1] + "米风速");
        map.put("ws50", "nwp" + windChangeName[2] + "米风速");
        map.put("ws70", "nwp" + windChangeName[3] + "米风速");
        map.put("ws80", "nwp" + windChangeName[4] + "米风速");
        map.put("ws90", "nwp" + windChangeName[5] + "米风速");
        map.put("ws100", "nwp" + windChangeName[6] + "米风速");
        map.put("ws170", "nwp" + windChangeName[7] + "米风速");
      } else {
        map.put("ws10", "nwp10米风速");
        map.put("ws30", "nwp30米风速");
        map.put("ws50", "nwp50米风速");
        map.put("ws70", "nwp70米风速");
        map.put("ws80", "nwp80米风速");
        map.put("ws90", "nwp90米风速");
        map.put("ws100", "nwp100米风速");
        map.put("ws170", "nwp170米风速");
      }
    } else {
      map.put("ws10", "nwp10米风速");
      map.put("ws30", "nwp30米风速");
      map.put("ws50", "nwp50米风速");
      map.put("ws70", "nwp70米风速");
      map.put("ws80", "nwp80米风速");
      map.put("ws90", "nwp90米风速");
      map.put("ws100", "nwp100米风速");
      map.put("ws170", "nwp170米风速");
    }

    return ResponseVO.success(map);
  }


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

  ) throws Exception {

    Map<String, Object> map = comprehensiveContrastService.comprehensiveContrast(startTime, endTime, no, otherType, dqAgo, cdqAgo, nwpAgo, jgTime);

    BufferedOutputStream bos = null;
    try {
      StringBuilder templateContent = new StringBuilder();
      response.setCharacterEncoding("UTF-8");
      ElectricField electricField = electricFieldService.get();
      DisplayConfig displayConfig = null;
      if ("E1".equals(otherType)) {
        displayConfig = displayConfigService.findByDisplayCode("weatherStationInfos");
        String showCode = displayConfig.getShowCode();
        String[] split = showCode.split(",");
        String header = "\"时间\",";

        String displayKyLl = (String) map.get("displayKyLl");

        for (int i = 0; i < split.length; i++) {
          switch (split[i]) {
            case "realValue":
              header += "\"实际功率\",";
              if (displayKyLl.equals("1")) {
                header += "\"可用功率\",\"理论功率\",\"参照功率（样板机）\",\"参照功率（测风、测光）\",";
              }
              break;
            case "dq":
              header += "\"上报短期\",";
              break;
            case "cdq":
              header += "\"上报超短期\",";
              break;
            case "globalR":
              header += "\"总辐射\",";
              break;
            case "directR":
              header += "\"直辐射\",";
              break;
            case "diffuseR":
              header += "\"散辐射\",";
              break;
            case "obliqueR":
              header += "\"斜辐射\",";
              break;
            case "directRadiation":
              header += "\"nwp直辐射\",";
              break;
            case "diffuseRadiation":
              header += "\"nwp散辐射\",";
              break;
            case "swr":
              header += "\"nwp总辐射\",";
              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") + ",");

                if (displayKyLl.equals("1")) {
                  content.append(tableResult.get(i).get("ableValue") + ",");
                  content.append(tableResult.get(i).get("theoryValue") + ",");
                  content.append(tableResult.get(i).get("referencePowerBySample") + ",");
                  content.append(tableResult.get(i).get("referencePowerByMeasuring") + ",");
                }
                break;
              case "dq":
                content.append(tableResult.get(i).get("dq") + ",");
                break;
              case "cdq":
                content.append(tableResult.get(i).get("cdq") + ",");
                break;
              case "globalR":
                content.append(resultList.get(i).get("globalR") + ",");
                break;
              case "directR":
                content.append(resultList.get(i).get("directR") + ",");
                break;
              case "diffuseR":
                content.append(resultList.get(i).get("diffuseR") + ",");
                break;
              case "obliqueR":
                content.append(resultList.get(i).get("obliqueR") + ",");
                break;
              case "directRadiation":
                content.append(resultList.get(i).get("directRadiation") + ",");
                break;
              case "diffuseRadiation":
                content.append(resultList.get(i).get("diffuseRadiation") + ",");
                break;
              case "swr":
                content.append(resultList.get(i).get("swr") + ",");
                break;
            }
          }
          content.append("\r\n");
          templateContent.append(content.toString());
        }

      } else {

        displayConfig = displayConfigService.findByDisplayCode("windTowerInfos");
        String showCode = displayConfig.getShowCode();
        String[] split = showCode.split(",");
        String header = "\"时间\",";

        String displayKyLl = (String) map.get("displayKyLl");

        for (int i = 0; i < split.length; i++) {
          switch (split[i]) {
            case "realValue":
              header += "\"实际功率\",";
              if (displayKyLl.equals("1")) {
                header += "\"可用功率\",\"理论功率\",\"参照功率（样板机）\",\"参照功率（测风、测光）\",";
              }
              break;
            case "wsInst10":
              header += "\"10米风速\",";
              break;
            case "wsInst30":
              header += "\"30米风速\",";
              break;
            case "wsInst50":
              header += "\"50米风速\",";
              break;
            case "wsInst60":
              header += "\"60米风速\",";
              break;
            case "wsInst70":
              header += "\"70米风速\",";
              break;
            case "wsInst80":
              header += "\"80米风速\",";
              break;
            case "wsInst90":
              header += "\"90米风速\",";
              break;
            case "wsInst100":
              header += "\"100米风速\",";
              break;
            case "wsInst110":
              header += "\"110米风速\",";
              break;
            case "wsInst120":
              header += "\"120米风速\",";
              break;
            case "ws10":
              header += "\"nwp10米风速\",";
              break;
            case "ws30":
              header += "\"nwp30米风速\",";
              break;
            case "ws50":
              header += "\"nwp50米风速\",";
              break;
            case "ws70":
              header += "\"nwp70米风速\",";
              break;
            case "ws80":
              header += "\"nwp80米风速\",";
              break;
            case "ws90":
              header += "\"nwp90米风速\",";
              break;
            case "ws110":
              header += "\"nwp100米风速\",";
              break;
            case "ws170":
              header += "\"nwp170米风速\",";
              break;
            case "dq":
              header += "\"上报短期\",";
              break;
            case "cdq":
              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") + ",");

                if (displayKyLl.equals("1")) {
                  content.append(tableResult.get(i).get("ableValue") + ",");
                  content.append(tableResult.get(i).get("theoryValue") + ",");
                  content.append(tableResult.get(i).get("referencePowerBySample") + ",");
                  content.append(tableResult.get(i).get("referencePowerByMeasuring") + ",");
                }
                break;
              case "wsInst10":
                content.append(resultList.get(i).get("wsInst10") + ",");
                break;
              case "wsInst30":
                content.append(resultList.get(i).get("wsInst30") + ",");
                break;
              case "wsInst50":
                content.append(resultList.get(i).get("wsInst50") + ",");
                break;
              case "wsInst60":
                content.append(resultList.get(i).get("wsInst60") + ",");
                break;
              case "wsInst70":
                content.append(resultList.get(i).get("wsInst70") + ",");
                break;
              case "wsInst80":
                content.append(resultList.get(i).get("wsInst80") + ",");
                break;
              case "wsInst90":
                content.append(resultList.get(i).get("wsInst90") + ",");
                break;
              case "wsInst100":
                content.append(resultList.get(i).get("wsInst100") + ",");
                break;
              case "wsInst110":
                content.append(resultList.get(i).get("wsInst110") + ",");
                break;
              case "wsInst120":
                content.append(resultList.get(i).get("wsInst120") + ",");
                break;
              case "ws10":
                content.append(resultList.get(i).get("ws10") + ",");
                break;
              case "ws30":
                content.append(resultList.get(i).get("ws30") + ",");
                break;
              case "ws50":
                content.append(resultList.get(i).get("ws50") + ",");
                break;
              case "ws70":
                content.append(resultList.get(i).get("ws70") + ",");
                break;
              case "ws80":
                content.append(resultList.get(i).get("ws80") + ",");
                break;
              case "ws90":
                content.append(resultList.get(i).get("ws90") + ",");
                break;
              case "ws110":
                content.append(resultList.get(i).get("ws110") + ",");
                break;
              case "ws170":
                content.append(resultList.get(i).get("ws170") + ",");
                break;
              case "dq":
                content.append(tableResult.get(i).get("dq") + ",");
                break;
              case "cdq":
                content.append(tableResult.get(i).get("cdq") + ",");
                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();
  }

  @GetMapping("/comprehensiveContrast/getSelects")
  public ResponseVO getSelects() {

    Map<String, List<Map<String, String>>> selects = comprehensiveContrastService.getSelects();

    return ResponseVO.success(selects);
  }



}
