package com.jiayue.ipfcst.dataexchange.service;

import com.jiayue.ipfcst.common.data.abst.equipmentinfo.AbstractEquipmentInfo;
import com.jiayue.ipfcst.common.data.constant.enums.EquipmentTypeEnum;
import com.jiayue.ipfcst.common.data.entity.EquipmentAttribute;
import com.jiayue.ipfcst.common.data.entity.ProtocolGatherDataPoint;
import com.jiayue.ipfcst.dataexchange.container.ProtocolDataContainer;
import com.jiayue.ipfcst.dataexchange.service.equipmentstatusdata.EquipmentInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 获取实时数据用于生成上报文件
 *
 * @author: xiuwei
 * @version:
 */
@Service
public class GetRealTimeDate4GenerateUploadFileService {


  private final ProtocolDataContainer protocolDataContainer = ProtocolDataContainer.getInstance();


  @Autowired
  EquipmentInfoService equipmentInfoService;

  @Autowired
  ProtocolGatherDataPointService protocolGatherDataPointService;

  @Autowired
  EquipmentAttributeService equipmentAttributeService;


  private Map<EquipmentTypeEnum, Map<AbstractEquipmentInfo, List<ProtocolGatherDataPoint>>> equipmentPoints = new HashMap<>();

  /**
   * 根据设备类型获取设备类型下的所有设备的数据
   * Map<设备信息，Map<点位属性(EquipmentAttribute的中文描述)，值>>
   * 没有该类型的设备的时候返回null
   * 设备下没有点位时 设备id对应的值为null
   *
   * @param equipmentType 设备类型
   * @return {@link Map<AbstractEquipmentInfo, Map<String,Object>>}
   */
  public Map<AbstractEquipmentInfo, Map<String, Object>> getDate(EquipmentTypeEnum equipmentType) {
    LinkedHashMap<AbstractEquipmentInfo, Map<String, Object>> date = new LinkedHashMap<>();
    Map<AbstractEquipmentInfo, List<ProtocolGatherDataPoint>> pointsMap = getEquipmentPoints(equipmentType);
    List<EquipmentAttribute> equipmentAttributes = equipmentAttributeService.getByEquipmentType(equipmentType);
    if (pointsMap == null) {
      return null;
    } else {
      TreeSet<AbstractEquipmentInfo> set = new TreeSet(new AbstractEquipmentInfoComparator());
      set.addAll(pointsMap.keySet());
      Iterator<AbstractEquipmentInfo> it = set.iterator();
      List<ProtocolGatherDataPoint> pointList;
      AbstractEquipmentInfo abstractEquipmentInfo;
      Map<String, Object> equipmentDates;
      Object o;
      while (it.hasNext()) {
        abstractEquipmentInfo = it.next();
        pointList = pointsMap.get(abstractEquipmentInfo);
        equipmentDates = new HashMap<>(equipmentAttributes.size());
        for (EquipmentAttribute e : equipmentAttributes) {
          equipmentDates.put(e.getExplanation(),"null");
        }
        if(pointList!=null){
          for (ProtocolGatherDataPoint p : pointList) {
            o = protocolDataContainer.getData(p.getId());
            if (o instanceof BigDecimal) {
              equipmentDates.put(p.getEquipmentAttribute().getExplanation(), ((BigDecimal) o).setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (o instanceof Boolean) {
              equipmentDates.put(p.getEquipmentAttribute().getExplanation(), (Boolean) o ? 1 : 0);
            }
          }
        }
        date.put(abstractEquipmentInfo, equipmentDates);
      }
      return date;
    }
  }


  /**
   * 获取到该设备类型下所有设备的点位
   * 没有该类型的设备的时候返回null
   * 设备下没有点位时 设备id对应的值为null
   *
   * @param equipmentType 设备类型
   * @return {@link Map<Integer, List<ProtocolGatherDataPoint>>}
   */
  private Map<AbstractEquipmentInfo, List<ProtocolGatherDataPoint>> getEquipmentPoints(EquipmentTypeEnum equipmentType) {
    if (this.equipmentPoints.containsKey(equipmentType)) {
      return this.equipmentPoints.get(equipmentType);
    } else {
      List<ProtocolGatherDataPoint> points;
      Map<AbstractEquipmentInfo, List<ProtocolGatherDataPoint>> pointMap = new HashMap<>();
      if (equipmentType == EquipmentTypeEnum.POWERSTATION) {
        points = protocolGatherDataPointService.getByEquipmentId(null, EquipmentTypeEnum.POWERSTATION);
        AbstractEquipmentInfo powerStation = new AbstractEquipmentInfo();
        powerStation.setEquipmentType(EquipmentTypeEnum.POWERSTATION);
        powerStation.setId(0);
        pointMap.put(powerStation, points);
        this.equipmentPoints.put(equipmentType, pointMap);
        return pointMap;
      }
      else if (equipmentType == EquipmentTypeEnum.POWERSTATION2) {
        points = protocolGatherDataPointService.getByEquipmentId(null, EquipmentTypeEnum.POWERSTATION2);
        AbstractEquipmentInfo powerStation = new AbstractEquipmentInfo();
        powerStation.setEquipmentType(EquipmentTypeEnum.POWERSTATION2);
        powerStation.setId(21);
        pointMap.put(powerStation, points);
        this.equipmentPoints.put(equipmentType, pointMap);
        return pointMap;
      } else {
        List<AbstractEquipmentInfo> list = equipmentInfoService.findByEqType(equipmentType);
        if (list.size() > 0) {
          for (AbstractEquipmentInfo abstractEquipmentInfo : list) {
            points = protocolGatherDataPointService.getByEquipmentId(abstractEquipmentInfo.getId(), abstractEquipmentInfo.getEquipmentType());
            if (points.size() > 0) {
              pointMap.put(abstractEquipmentInfo, points);
            } else {
              pointMap.put(abstractEquipmentInfo, null);
            }
          }
          this.equipmentPoints.put(equipmentType, pointMap);
          return pointMap;
        } else {
          this.equipmentPoints.put(equipmentType, null);
          return null;
        }
      }
    }
  }


  private class AbstractEquipmentInfoComparator implements Comparator<AbstractEquipmentInfo> {

    @Override
    public int compare(AbstractEquipmentInfo o1, AbstractEquipmentInfo o2) {
      return o1.getId() - o2.getId();
    }
  }


}
