package com.jiayue.ipfcst.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.jiayue.ipfcst.common.data.entity.AccuracyPassRate;
import com.jiayue.ipfcst.common.data.entity.AccuracyPassRateDay;
import com.jiayue.ipfcst.common.data.repository.AccuracyPassRateDayRepository;
import com.jiayue.ipfcst.common.data.repository.AccuracyPassRateRepository;
import com.jiayue.ipfcst.common.data.repository.DisplayConfigRepository;
import com.jiayue.ipfcst.common.data.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 准确合格率业务层11
 *
 * @author yh
 * @version 1.0
 * @since 2019/8/5 16:02
 */
@Service
@Slf4j
public class AccuracyPassRateService extends BaseService {
  private final AccuracyPassRateRepository accuracyPassRateRepository;
  private final AccuracyPassRateDayRepository accuracyPassRateDayRepository;
  private final DisplayConfigRepository displayConfigRepository;

  @Autowired
  public AccuracyPassRateService(AccuracyPassRateRepository accuracyPassRateRepository,
                                 AccuracyPassRateDayRepository accuracyPassRateDayRepository,
                                 DisplayConfigRepository displayConfigRepository) {
    this.accuracyPassRateRepository = accuracyPassRateRepository;
    this.accuracyPassRateDayRepository = accuracyPassRateDayRepository;
    this.displayConfigRepository = displayConfigRepository;
  }

  /**
   * 根据时间查询准确率合格率 yh
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param page      页码
   * @param size      条数
   * @param sortOrder 排序
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenAndNoForPaging(Long startTime, Long endTime,
                                                             Integer page, Integer size,
                                                             String sortOrder) {
    Map<String, Object> map = new HashMap<>();
    Sort sort = Sort.by(Sort.Direction.DESC, "time");
    if (sortOrder.contains("asc")) {
      sort = Sort.by(Sort.Direction.ASC, "time");
    }
    Specification<AccuracyPassRate> specification = this.specificationFindByTime(startTime, endTime);
    Pageable pageable = PageRequest.of(page - 1, size, sort);
    Page AccuracyPassRates = accuracyPassRateRepository.findAll(specification, pageable);
    List<AccuracyPassRate> datas = new ArrayList<>();
    datas = AccuracyPassRates.getContent();
    map.put("content", datas);
    map.put("count", AccuracyPassRates.getTotalElements());
    return map;
  }


  /**
   * 根据时间查询准确率合格率 yh
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param sortOrder 排序
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenTable(Long startTime, Long endTime,
                                                    String showCode,
                                                    String sortOrder) throws NoSuchFieldException, IllegalAccessException {
    Map<String, Object> map = new HashMap<>();
    List<AccuracyPassRate> byTimeBetween = new ArrayList<>();

    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    if (endTime % timeStep != 0) {
      endTime = endTime - (endTime % timeStep);
    }

    byTimeBetween = accuracyPassRateRepository.findByTimeBetween(startTime, endTime);

    List<AccuracyPassRate> allList = checkData(startTime, endTime, byTimeBetween, timeStep);

    //DAY  按照一天1条显示 也就是每天23:45那条    TIME  按照15分钟一条展示
    String sysParameter = super.getSysParameter("ACCURACY_RATE_SHOW", "day");

    List<AccuracyPassRate> result = new ArrayList<>();
    SimpleDateFormat sdf;
    if (sysParameter.equals("day")) {

      sdf = new SimpleDateFormat("yyyy-MM-dd");
      String endTimeStr = sdf.format(DateUtil.date(endTime));
      List<DateTime> dateTimes = DateUtil.rangeToList(new Date(startTime), new Date(endTime), DateField.DAY_OF_YEAR);
      for (int i = 0; i < dateTimes.size(); i++) {
        String format = sdf.format(dateTimes.get(i));
        //如果是最后时间，就拿最后时间整15分钟的
        if (format.equals(endTimeStr)) {
          long finalNowTime = endTime;
          List<AccuracyPassRate> collect = allList.stream().filter(a -> a.getTime() == finalNowTime).collect(Collectors.toList());
          result.add(collect.get(0));
        } else {
          //如果不是 就拿这天23:45的
          int year = dateTimes.get(i).getField(DateField.YEAR);
          int month = dateTimes.get(i).getField(DateField.MONTH) + 1;
          int day = dateTimes.get(i).getField(DateField.DAY_OF_MONTH);
          long time = new GregorianCalendar(year, month - 1, day, 23, 45, 00).getTime().getTime();
          List<AccuracyPassRate> collect = allList.stream().filter(a -> a.getTime() == time).collect(Collectors.toList());
          result.add(collect.get(0));
        }
      }

    } else {
      sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      result = allList;
    }

    if (sortOrder.contains("asc")) {
      result.sort(Comparator.comparing(AccuracyPassRate::getTime));
    } else {
      result.sort(Comparator.comparing(AccuracyPassRate::getTime).reversed());
    }

    List<Map<String, Object>> resultList = new ArrayList<>();
    String[] displayCode = showCode.split(",");

    List<String> shortTermAccuracys = new ArrayList<>();
    List<String> shortTermPassRate = new ArrayList<>();
    List<String> ultraShortTermAccuracy = new ArrayList<>();
    List<String> ultraShortTermPassRate = new ArrayList<>();
    List<String> times = new ArrayList<>();
    Map<String, Object> chartsMap = new HashMap<>();
    String accuracyRate = super.getSysParameter("ACCURACY_RATE", "75,85");
    chartsMap.put("accuracyRate", accuracyRate);
    for (int i = 0; i < result.size(); i++) {
      Map<String, Object> dtoM = new HashMap<>();
      AccuracyPassRate apr = result.get(i);
      dtoM.put("time", sdf.format(new Date(apr.getTime())));
      times.add(sdf.format(new Date(apr.getTime())));
  /*    Class c = apr.getClass();
      Field f;*/
      for (int j = 0; j < displayCode.length; j++) {

        if (displayCode[j].equals("shortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getShortTermAccuracy());
          if (apr.getShortTermAccuracy() != null && apr.getShortTermAccuracy().equals("无可用数据计算")) {
            shortTermAccuracys.add(null);
          } else {
            if(apr.getShortTermAccuracy() != null && !apr.getShortTermAccuracy().equals("不予考核")){
              shortTermAccuracys.add(apr.getShortTermAccuracy());
            }

          }

        }
        if (displayCode[j].equals("shortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getShortTermPassRate());
          if (apr.getShortTermPassRate() != null && apr.getShortTermPassRate().equals("无可用数据计算")) {
            shortTermPassRate.add(null);
          } else {
            shortTermPassRate.add(apr.getShortTermPassRate());
          }
        }
        if (displayCode[j].equals("ultraShortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermAccuracy());
          if (apr.getUltraShortTermAccuracy() != null && apr.getUltraShortTermAccuracy().equals("无可用数据计算")) {
            ultraShortTermAccuracy.add(null);
          } else {
            if(apr.getUltraShortTermAccuracy() != null && !apr.getUltraShortTermAccuracy().equals("不予考核")){
              ultraShortTermAccuracy.add(apr.getUltraShortTermAccuracy());
            }

          }
        }
        if (displayCode[j].equals("ultraShortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermPassRate());
          if (apr.getUltraShortTermPassRate() != null && apr.getUltraShortTermPassRate().equals("无可用数据计算")) {
            ultraShortTermPassRate.add(null);
          } else {
            ultraShortTermPassRate.add(apr.getUltraShortTermPassRate());
          }
        }

       /* f = c.getDeclaredField(displayCode[j]);
        f.setAccessible(true);
        f.get(apr);
        dtoM.put(displayCode[j], f.get(apr));*/
      }
      resultList.add(dtoM);
    }

    chartsMap.put("times", times);

    for (int i = 0; i < displayCode.length; i++) {
      if (displayCode[i].equals("shortTermAccuracy")) {
        chartsMap.put(displayCode[i], shortTermAccuracys);
      }
      if (displayCode[i].equals("shortTermPassRate")) {
        chartsMap.put(displayCode[i], shortTermPassRate);
      }
      if (displayCode[i].equals("ultraShortTermAccuracy")) {
        chartsMap.put(displayCode[i], ultraShortTermAccuracy);
      }
      if (displayCode[i].equals("ultraShortTermPassRate")) {
        chartsMap.put(displayCode[i], ultraShortTermPassRate);
      }
    }

    map.put("content", resultList);
    map.put("charts", chartsMap);

    return map;
  }

  /**
   * 根据时间查询日准确率合格率 yh(表格)
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param sortOrder 排序
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenTableDay(Long startTime, Long endTime,
                                                       String showCode,
                                                       String sortOrder) throws NoSuchFieldException, IllegalAccessException {
    Map<String, Object> map = new HashMap<>();
    List<AccuracyPassRateDay> byTimeBetween = new ArrayList<>();

    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    if (endTime % timeStep != 0) {
      endTime = endTime - (endTime % timeStep);
    }
    // 根据时间，获取准确率数据
    byTimeBetween = accuracyPassRateDayRepository.findByTimeBetween(startTime, endTime);
    // 补全日数据
    List<AccuracyPassRateDay> allList = checkDataDay(startTime, endTime, byTimeBetween);
    //DAY  按照一天1条显示 也就是每天23:45那条    TIME  按照15分钟一条展示
    String sysParameter = super.getSysParameter("ACCURACY_RATE_SHOW", "day");

    List<AccuracyPassRateDay> accuracyPassRateDayList = new ArrayList<>();
    SimpleDateFormat sdf;
    if (sysParameter.equals("day")) {
      accuracyPassRateDayList.addAll(allList);
      sdf = new SimpleDateFormat("yyyy-MM-dd");
//      String endTimeStr = sdf.format(DateUtil.date(endTime));
//      List<DateTime> dateTimes = DateUtil.rangeToList(new Date(startTime), new Date(endTime), DateField.DAY_OF_YEAR);
//      for (int i = 0; i < dateTimes.size(); i++) {
//        String format = sdf.format(dateTimes.get(i));
//        //如果是最后时间，就拿最后时间整15分钟的
//        if (format.equals(endTimeStr)) {
//          long finalNowTime = endTime;
//          List<AccuracyPassRateDay> collect = allList.stream().filter(a -> a.getTime() == finalNowTime).collect(Collectors.toList());
//          result.add(collect.get(0));
//        } else {
//          //如果不是 就拿这天23:45的
//          int year = dateTimes.get(i).getField(DateField.YEAR);
//          int month = dateTimes.get(i).getField(DateField.MONTH) + 1;
//          int day = dateTimes.get(i).getField(DateField.DAY_OF_MONTH);
//          long time = new GregorianCalendar(year, month - 1, day, 23, 45, 00).getTime().getTime();
//          List<AccuracyPassRateDay> collect = allList.stream().filter(a -> a.getTime() == time).collect(Collectors.toList());
//          result.add(collect.get(0));
//        }
//      }

    } else {
      sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      accuracyPassRateDayList = allList;
    }

    if (sortOrder.contains("asc")) {
      accuracyPassRateDayList.sort(Comparator.comparing(AccuracyPassRateDay::getTime));
    } else {
      accuracyPassRateDayList.sort(Comparator.comparing(AccuracyPassRateDay::getTime).reversed());
    }

    List<Map<String, Object>> resultList = new ArrayList<>();
    String[] displayCode = showCode.split(",");

    List<String> shortTermAccuracys = new ArrayList<>();
    List<String> shortTermPassRate = new ArrayList<>();
    List<String> ultraShortTermAccuracy = new ArrayList<>();
    List<String> ultraShortTermPassRate = new ArrayList<>();
    List<String> times = new ArrayList<>();
    Map<String, Object> chartsMap = new HashMap<>();
    String accuracyRate = super.getSysParameter("ACCURACY_RATE", "75,85");
    chartsMap.put("accuracyRate", accuracyRate);
    for (int i = 0; i < accuracyPassRateDayList.size(); i++) {
      Map<String, Object> dtoM = new HashMap<>();
      AccuracyPassRateDay apr = accuracyPassRateDayList.get(i);
      dtoM.put("time", sdf.format(new Date(apr.getTime())));
      times.add(sdf.format(new Date(apr.getTime())));
  /*    Class c = apr.getClass();
      Field f;*/
      for (int j = 0; j < displayCode.length; j++) {

        if (displayCode[j].equals("shortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getShortTermAccuracy());
          if (apr.getShortTermAccuracy() != null && apr.getShortTermAccuracy().equals("无可用数据计算")) {
            shortTermAccuracys.add(null);
          } else {
            if (apr.getShortTermAccuracy() != null && !apr.getShortTermAccuracy().equals("不予考核")) {
              shortTermAccuracys.add(apr.getShortTermAccuracy());
            }
          }
        }
        if (displayCode[j].equals("shortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getShortTermPassRate());
          if (apr.getShortTermPassRate() != null && apr.getShortTermPassRate().equals("无可用数据计算")) {
            shortTermPassRate.add(null);
          } else {
            shortTermPassRate.add(apr.getShortTermPassRate());
          }
        }
        if (displayCode[j].equals("ultraShortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermAccuracy());
          if (apr.getUltraShortTermAccuracy() != null && apr.getUltraShortTermAccuracy().equals("无可用数据计算")) {
            ultraShortTermAccuracy.add(null);
          } else {
            if (apr.getShortTermAccuracy() != null && !apr.getUltraShortTermAccuracy().equals("不予考核")) {
              ultraShortTermAccuracy.add(apr.getUltraShortTermAccuracy());
            }
          }
        }
        if (displayCode[j].equals("ultraShortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermPassRate());
          if (apr.getUltraShortTermPassRate() != null && apr.getUltraShortTermPassRate().equals("无可用数据计算")) {
            ultraShortTermPassRate.add(null);
          } else {
            ultraShortTermPassRate.add(apr.getUltraShortTermPassRate());
          }
        }
      }
      resultList.add(dtoM);
    }

    chartsMap.put("times", times);

    for (int i = 0; i < displayCode.length; i++) {
      if (displayCode[i].equals("shortTermAccuracy")) {
        chartsMap.put(displayCode[i], shortTermAccuracys);
      }
      if (displayCode[i].equals("shortTermPassRate")) {
        chartsMap.put(displayCode[i], shortTermPassRate);
      }
      if (displayCode[i].equals("ultraShortTermAccuracy")) {
        chartsMap.put(displayCode[i], ultraShortTermAccuracy);
      }
      if (displayCode[i].equals("ultraShortTermPassRate")) {
        chartsMap.put(displayCode[i], ultraShortTermPassRate);
      }
    }

    map.put("content", resultList);
    map.put("charts", chartsMap);

    return map;
  }


  /**
   * 根据时间查询月准确率合格率
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param sortOrder 排序
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenTableMonth(Long startTime, Long endTime,
                                                         String showCode,
                                                         String sortOrder) throws NoSuchFieldException, IllegalAccessException {
    Map<String, Object> map = new HashMap<>();
    List<AccuracyPassRate> allList = new ArrayList<>();

    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    if (endTime % timeStep != 0) {
      endTime = endTime - (endTime % timeStep);
    }

    allList = accuracyPassRateRepository.findByTimeBetween(startTime, endTime);



    List<AccuracyPassRate> result = new ArrayList<>();
    SimpleDateFormat sdf;

    sdf = new SimpleDateFormat("yyyy-MM");
    DecimalFormat df = new DecimalFormat("0.00");

    List<DateTime> dateTimes = DateUtil.rangeToList(new Date(startTime), new Date(endTime), DateField.MONTH);
    for (int i = 0; i < dateTimes.size(); i++) {
      String format = sdf.format(dateTimes.get(i));
      List<AccuracyPassRate> collect = allList.stream().filter(s -> sdf.format(s.getTime()).equals(format)).collect(Collectors.toList());

      List<Double> shortTermAccuracyList = new ArrayList<>();
      List<Double> shortTermPassRateList = new ArrayList<>();
      List<Double> ultraShortTermAccuracyList = new ArrayList<>();
      List<Double> ultraShortTermPassRateList = new ArrayList<>();

      for (AccuracyPassRate accuracyPassRate : collect) {
        if(accuracyPassRate.getShortTermAccuracy() != null ){
          if (accuracyPassRate.getShortTermAccuracy().indexOf("%") >= 0) {
            try {
              shortTermAccuracyList.add(Double.parseDouble(accuracyPassRate.getShortTermAccuracy().split("%")[0]));
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
        if(accuracyPassRate.getShortTermPassRate() != null ){
          if (accuracyPassRate.getShortTermPassRate().indexOf("%") >= 0) {
            try {
              shortTermPassRateList.add(Double.parseDouble(accuracyPassRate.getShortTermPassRate().split("%")[0]));
            } catch (Exception e) {
              e.printStackTrace();
            }

          }
        }
        if(accuracyPassRate.getUltraShortTermAccuracy() !=null ){
          if (accuracyPassRate.getUltraShortTermAccuracy().indexOf("%") >= 0) {
            try {
              ultraShortTermAccuracyList.add(Double.parseDouble(accuracyPassRate.getUltraShortTermAccuracy().split("%")[0]));
            } catch (Exception e) {
              e.printStackTrace();
            }

          }
        }
        if(accuracyPassRate.getUltraShortTermPassRate()!=null){
          if (accuracyPassRate.getUltraShortTermPassRate().indexOf("%") >= 0) {
            try {
              ultraShortTermPassRateList.add(Double.parseDouble(accuracyPassRate.getUltraShortTermPassRate().split("%")[0]));
            } catch (Exception e) {
              e.printStackTrace();
            }
          }

        }
        }


      AccuracyPassRate newAccuracyPassRate = new AccuracyPassRate();
      if(shortTermAccuracyList.size()>0){
        double shortTermAccuracyAvg = shortTermAccuracyList.stream().mapToDouble(d -> d.doubleValue()).average().getAsDouble();
        newAccuracyPassRate.setShortTermAccuracy(df.format(shortTermAccuracyAvg) + "%");
      }else {
        newAccuracyPassRate.setShortTermAccuracy("无可用数据");
      }
      if(shortTermPassRateList.size()>0){
        double shortTermPassRateAvg = shortTermPassRateList.stream().mapToDouble(d -> d.doubleValue()).average().getAsDouble();
        newAccuracyPassRate.setShortTermPassRate(df.format(shortTermPassRateAvg) + "%");
      }else {
        newAccuracyPassRate.setShortTermPassRate("无可用数据");
      }
      if(ultraShortTermAccuracyList.size()>0){
        double ultraShortTermAccuracyAvg = ultraShortTermAccuracyList.stream().mapToDouble(d -> d.doubleValue()).average().getAsDouble();
        newAccuracyPassRate.setUltraShortTermAccuracy(df.format(ultraShortTermAccuracyAvg) + "%");
      }else {
        newAccuracyPassRate.setUltraShortTermAccuracy("无可用数据");
      }
      if(ultraShortTermPassRateList.size()>0){
        double ultraShortTermPassRateAvg = ultraShortTermPassRateList.stream().mapToDouble(d -> d.doubleValue()).average().getAsDouble();
        newAccuracyPassRate.setUltraShortTermPassRate(df.format(ultraShortTermPassRateAvg) + "%");
      }else {
        newAccuracyPassRate.setUltraShortTermPassRate("无可用数据");
      }
      newAccuracyPassRate.setTime(dateTimes.get(i).getTime());

      result.add(newAccuracyPassRate);
    }

    if (sortOrder.contains("asc")) {
      result.sort(Comparator.comparing(AccuracyPassRate::getTime));
    } else {
      result.sort(Comparator.comparing(AccuracyPassRate::getTime).reversed());
    }

    List<Map<String, Object>> resultList = new ArrayList<>();
    String[] displayCode = showCode.split(",");

    List<String> shortTermAccuracys = new ArrayList<>();
    List<String> shortTermPassRate = new ArrayList<>();
    List<String> ultraShortTermAccuracy = new ArrayList<>();
    List<String> ultraShortTermPassRate = new ArrayList<>();
    List<String> times = new ArrayList<>();
    Map<String, Object> chartsMap = new HashMap<>();
    String accuracyRate = super.getSysParameter("ACCURACY_RATE", "75,85");
    chartsMap.put("accuracyRate", accuracyRate);
    for (int i = 0; i < result.size(); i++) {
      Map<String, Object> dtoM = new HashMap<>();
      AccuracyPassRate apr = result.get(i);
      dtoM.put("time", sdf.format(new Date(apr.getTime())));
      times.add(sdf.format(new Date(apr.getTime())));
  /*    Class c = apr.getClass();
      Field f;*/
      for (int j = 0; j < displayCode.length; j++) {

        if (displayCode[j].equals("shortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getShortTermAccuracy());
          if (apr.getShortTermAccuracy() != null && apr.getShortTermAccuracy().equals("无可用数据计算")) {
            shortTermAccuracys.add(null);
          } else {
            shortTermAccuracys.add(apr.getShortTermAccuracy());
          }

        }
        if (displayCode[j].equals("shortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getShortTermPassRate());
          if (apr.getShortTermPassRate() != null && apr.getShortTermPassRate().equals("无可用数据计算")) {
            shortTermPassRate.add(null);
          } else {
            shortTermPassRate.add(apr.getShortTermPassRate());
          }
        }
        if (displayCode[j].equals("ultraShortTermAccuracy")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermAccuracy());
          if (apr.getUltraShortTermAccuracy() != null && apr.getUltraShortTermAccuracy().equals("无可用数据计算")) {
            ultraShortTermAccuracy.add(null);
          } else {
            ultraShortTermAccuracy.add(apr.getUltraShortTermAccuracy());
          }
        }
        if (displayCode[j].equals("ultraShortTermPassRate")) {
          dtoM.put(displayCode[j], apr.getUltraShortTermPassRate());
          if (apr.getUltraShortTermPassRate() != null && apr.getUltraShortTermPassRate().equals("无可用数据计算")) {
            ultraShortTermPassRate.add(null);
          } else {
            ultraShortTermPassRate.add(apr.getUltraShortTermPassRate());
          }
        }

       /* f = c.getDeclaredField(displayCode[j]);
        f.setAccessible(true);
        f.get(apr);
        dtoM.put(displayCode[j], f.get(apr));*/
      }
      resultList.add(dtoM);
    }

    chartsMap.put("times", times);

    for (int i = 0; i < displayCode.length; i++) {

      if (displayCode[i].equals("shortTermAccuracy")) {

        chartsMap.put(displayCode[i], shortTermAccuracys);
      }

      if (displayCode[i].equals("shortTermPassRate")) {

        chartsMap.put(displayCode[i], shortTermPassRate);
      }

      if (displayCode[i].equals("ultraShortTermAccuracy")) {

        chartsMap.put(displayCode[i], ultraShortTermAccuracy);
      }

      if (displayCode[i].equals("ultraShortTermPassRate")) {

        chartsMap.put(displayCode[i], ultraShortTermPassRate);
      }

    }

    map.put("content", resultList);
    map.put("charts", chartsMap);

    return map;
  }


  /**
   * 当天实时准确率合格率 yh
   *
   * @param startTime 开始时间 当天凌晨
   * @param endTime   结束时间 当前时间
   * @param showCode  展示配置
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenForRealTimeCharts(Long startTime, Long endTime, String showCode) {

    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }

    if (endTime % timeStep != 0) {
      endTime = endTime - (endTime % timeStep);
    }

    List<AccuracyPassRate> byTimeBetween = accuracyPassRateRepository.findByTimeBetween(startTime, endTime);

    String accuracyRate = super.getSysParameter("ACCURACY_RATE", "75,85");

    List<AccuracyPassRate> allList = checkData(startTime, endTime, byTimeBetween, timeStep);
    //过滤数据
    exchangeValue(allList);

    allList.sort(Comparator.comparing(AccuracyPassRate::getTime));

    String[] displayCode = showCode.split(",");


    Map<String, Object> map = new HashMap<>();

    List<String> times = new ArrayList<>();
    map.put("times", times);

    map.put("accuracyRate", accuracyRate);

    List<String> shortTermAccuracys = new ArrayList<>();
    List<String> shortTermPassRate = new ArrayList<>();
    List<String> ultraShortTermAccuracy = new ArrayList<>();
    List<String> ultraShortTermPassRate = new ArrayList<>();

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    for (int i = 0; i < allList.size(); i++) {
      Long time = allList.get(i).getTime();
      times.add(sdf.format(new Date(time)));

      for (int j = 0; j < displayCode.length; j++) {

        if (displayCode[j].equals("shortTermAccuracy")) {
          String str = allList.get(i).getShortTermAccuracy();
          shortTermAccuracys.add(str);
        }

        if (displayCode[j].equals("shortTermPassRate")) {
          String str = allList.get(i).getShortTermPassRate();
          shortTermPassRate.add(str);
        }

        if (displayCode[j].equals("ultraShortTermAccuracy")) {
          String str = allList.get(i).getUltraShortTermAccuracy();
          ultraShortTermAccuracy.add(str);
        }

        if (displayCode[j].equals("ultraShortTermPassRate")) {
          String str = allList.get(i).getUltraShortTermPassRate();
          ultraShortTermPassRate.add(str);
        }
      }

    }

    for (int i = 0; i < displayCode.length; i++) {


      if (displayCode[i].equals("shortTermAccuracy")) {

        map.put(displayCode[i], shortTermAccuracys);
      }

      if (displayCode[i].equals("shortTermPassRate")) {

        map.put(displayCode[i], shortTermPassRate);
      }

      if (displayCode[i].equals("ultraShortTermAccuracy")) {

        map.put(displayCode[i], ultraShortTermAccuracy);
      }

      if (displayCode[i].equals("ultraShortTermPassRate")) {

        map.put(displayCode[i], ultraShortTermPassRate);
      }

    }

    return map;
  }


  /**
   * 日准确率合格率 yh(用于图表)
   *
   * @param startTime 开始时间 当天凌晨
   * @param endTime   结束时间 当前时间
   * @param showCode  展示配置
   * @return
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String, Object> findByTimeBetweenForRealTimeChartsDay(Long startTime, Long endTime, String showCode) {
    // 根据检索的时间段，查询准确率数据
    List<AccuracyPassRateDay> byTimeBetween = accuracyPassRateDayRepository.findByTimeBetween(startTime, endTime);
    // 设定默认准确率
    String accuracyRate = super.getSysParameter("ACCURACY_RATE", "75,85");
    // 补全时间段内数据
    List<AccuracyPassRateDay> allList = checkDataDay(startTime, endTime, byTimeBetween);
    //过滤数据
    exchangeValueDay(allList);
    // 根据时间排序
    allList.sort(Comparator.comparing(AccuracyPassRateDay::getTime));

    String[] displayCode = showCode.split(",");

    Map<String, Object> resultMap = new HashMap<>();

    List<String> times = new ArrayList<>();
    resultMap.put("times", times);
    resultMap.put("accuracyRate", accuracyRate);

    List<String> shortTermAccuracys = new ArrayList<>();
    List<String> shortTermPassRate = new ArrayList<>();
    List<String> ultraShortTermAccuracy = new ArrayList<>();
    List<String> ultraShortTermPassRate = new ArrayList<>();

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    // 循环数据，并分别组建短期准确率、短期合格率、超短期准确率、超短期合格率
    for (int i = 0; i < allList.size(); i++) {
      times.add(sdf.format(new Date(allList.get(i).getTime())));
      // 循环displayCode，并组建数据
      for (int j = 0; j < displayCode.length; j++) {
        // 如果是短期准确率
        if (displayCode[j].equals("shortTermAccuracy")) {
          shortTermAccuracys.add(allList.get(i).getShortTermAccuracy());
        }
        // 如果是短期合格率
        if (displayCode[j].equals("shortTermPassRate")) {
          shortTermPassRate.add(allList.get(i).getShortTermPassRate());
        }
        // 如果是超短期准确率
        if (displayCode[j].equals("ultraShortTermAccuracy")) {
          ultraShortTermAccuracy.add(allList.get(i).getUltraShortTermAccuracy());
        }
        // 如果是超短期合格率
        if (displayCode[j].equals("ultraShortTermPassRate")) {
          ultraShortTermPassRate.add(allList.get(i).getUltraShortTermPassRate());
        }
      }
    }

    // 循环displayCode，并将结果放入resultMap
    for (int i = 0; i < displayCode.length; i++) {
      if (displayCode[i].equals("shortTermAccuracy")) {
        resultMap.put(displayCode[i], shortTermAccuracys);
      }
      if (displayCode[i].equals("shortTermPassRate")) {
        resultMap.put(displayCode[i], shortTermPassRate);
      }
      if (displayCode[i].equals("ultraShortTermAccuracy")) {
        resultMap.put(displayCode[i], ultraShortTermAccuracy);
      }
      if (displayCode[i].equals("ultraShortTermPassRate")) {
        resultMap.put(displayCode[i], ultraShortTermPassRate);
      }
    }

    return resultMap;
  }

  /**
   * @param startTime     开始时间
   * @param endTime       结束时间
   * @param byTimeBetween 需要补全时间的数据
   * @param timeStep      时间间隔
   * @return 补全后数据
   */
  private List<AccuracyPassRate> checkData(Long startTime, Long endTime, List<AccuracyPassRate> byTimeBetween, long timeStep) {
    List<AccuracyPassRate> rtList = new ArrayList<>();
    //补全数据
    for (long i = startTime; i <= endTime; i = i + timeStep) {
      long finalI = i;
      List<AccuracyPassRate> a = byTimeBetween.stream().filter(t -> t.getTime() == finalI).collect(Collectors.toList());
      if (a != null && a.size() > 0) {
        AccuracyPassRate aResult = a.get(0);
        rtList.add(aResult);
      } else {
        AccuracyPassRate accuracyPassRate = new AccuracyPassRate();
        accuracyPassRate.setTime(finalI);
        rtList.add(accuracyPassRate);
      }
    }
    return rtList;
  }

  /**
   * @param startTime     开始时间
   * @param endTime       结束时间
   * @param byTimeBetween 需要补全时间的数据
   * @return 补全后数据
   */
  private List<AccuracyPassRateDay> checkDataDay(Long startTime, Long endTime, List<AccuracyPassRateDay> byTimeBetween) {
    List<AccuracyPassRateDay> resultList = new ArrayList<>();
    // 根据时间段，将时间段以日期为单位转为list
    List<DateTime> dateTimes = DateUtil.rangeToList(new Date(startTime), new Date(endTime), DateField.DAY_OF_YEAR);
    //补全数据
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    for (int i = 0; i < dateTimes.size(); i++) {
      int finalI = i;
      // 根据准确率数据中，是否包含时间段中的时间(格式化时间为yyyy-MM-dd并对比)
      List<AccuracyPassRateDay> checkInclude = byTimeBetween.stream().filter(t -> sdf.format(DateUtil.date(t.getTime())).equals(sdf.format(dateTimes.get(finalI)))).sorted(Comparator.comparing(AccuracyPassRateDay::getId).reversed()).collect(Collectors.toList());
      // 如果包含，则放入数据
      if (checkInclude != null && checkInclude.size() > 0) {
        // 获取最新一条
        AccuracyPassRateDay aResult = checkInclude.get(0);
        resultList.add(aResult);
      // 如果不包含，则只插入时间
      } else {
        AccuracyPassRateDay accuracyPassRateDay = new AccuracyPassRateDay();
        accuracyPassRateDay.setTime(dateTimes.get(finalI).getTime());
        resultList.add(accuracyPassRateDay);
      }
    }
    return resultList;
  }



  /**
   * 查询条件 yh
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return 过滤条件
   */
  Specification<AccuracyPassRate> specificationFindByTime(final Long startTime, final Long endTime) {
    return (Specification<AccuracyPassRate>) (root, criteriaQuery, cb) -> {


      List<Predicate> predicates = new ArrayList<>();
      if (startTime != null) {
        //大于或等于传入时间
        predicates.add(cb.greaterThanOrEqualTo(root.get("time").as(Long.class), startTime));
      }
      if (endTime != null) {
        //小于传入时间
        predicates.add(cb.lessThan(root.get("time").as(Long.class), endTime));
      }
      //添加排序的功能
      return cb.and(predicates.toArray(new Predicate[predicates.size()]));

    };
  }

  /**
   * 更换数据
   *
   * @param rateList 需要更换数据的集合
   */
  private void exchangeValue(List<AccuracyPassRate> rateList) {
    for (int i = 0; i < rateList.size(); i++) {
      String shortTermAccuracy = rateList.get(i).getShortTermAccuracy();
      String ultraShortTermAccuracy = rateList.get(i).getUltraShortTermAccuracy();
      String shortTermPassRate = rateList.get(i).getShortTermPassRate();
      String ultraShortTermPassRate = rateList.get(i).getUltraShortTermPassRate();
      if (shortTermAccuracy != null && shortTermAccuracy.equals("无可用数据计算")) {
        rateList.get(i).setShortTermAccuracy(null);
      }
      if (ultraShortTermAccuracy != null && ultraShortTermAccuracy.equals("无可用数据计算")) {
        rateList.get(i).setUltraShortTermAccuracy(null);
      }
      if (shortTermPassRate != null && shortTermPassRate.equals("无可用数据计算")) {
        rateList.get(i).setShortTermPassRate(null);
      }
      if (ultraShortTermPassRate != null && ultraShortTermPassRate.equals("无可用数据计算")) {
        rateList.get(i).setUltraShortTermPassRate(null);
      }
    }
  }

  /**
   * 更换数据
   *
   * @param rateList 需要更换数据的集合
   */
  private void exchangeValueDay(List<AccuracyPassRateDay> rateList) {
    for (int i = 0; i < rateList.size(); i++) {
      String shortTermAccuracy = rateList.get(i).getShortTermAccuracy();
      String ultraShortTermAccuracy = rateList.get(i).getUltraShortTermAccuracy();
      String shortTermPassRate = rateList.get(i).getShortTermPassRate();
      String ultraShortTermPassRate = rateList.get(i).getUltraShortTermPassRate();
      if (shortTermAccuracy != null && shortTermAccuracy.equals("无可用数据计算")) {
        rateList.get(i).setShortTermAccuracy(null);
      }
      if (ultraShortTermAccuracy != null && ultraShortTermAccuracy.equals("无可用数据计算")) {
        rateList.get(i).setUltraShortTermAccuracy(null);
      }
      if (shortTermPassRate != null && shortTermPassRate.equals("无可用数据计算")) {
        rateList.get(i).setShortTermPassRate(null);
      }
      if (ultraShortTermPassRate != null && ultraShortTermPassRate.equals("无可用数据计算")) {
        rateList.get(i).setUltraShortTermPassRate(null);
      }
    }
  }


}
