package com.jiayue.ipfcst.dataexchange.service;

import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.data.constant.enums.DataSourceEnum;
import com.jiayue.ipfcst.common.data.entity.EquipmentAttribute;
import com.jiayue.ipfcst.common.data.entity.ProtocolGatherDataPoint;
import com.jiayue.ipfcst.console.service.ElectricFieldService;
import com.jiayue.ipfcst.dataexchange.domain.EquipmentDataTemplate;
import com.jiayue.ipfcst.dataexchange.domain.TemplatePoint;
import com.jiayue.ipfcst.dataexchange.repository.EquipmentDataTemplateRepository;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 模版的服务类
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
@Service
public class EquipmentDataTemplateService {


  private final
  EquipmentDataTemplateRepository equipmentDataTemplateRepository;

  private final
  TemplatePointService templatePointService;

  private final EquipmentAttributeService equipmentAttributeService;

  private final ProtocolGatherDataPointService protocolGatherDataPointService;

  private final ElectricFieldService electricFieldService;


  /**
   * 构造方法
   *
   * @param equipmentDataTemplateRepository 仓储
   * @param templatePointService            模版点位操作类
   * @param equipmentAttributeService       设备属性操作类
   * @param protocolGatherDataPointService  采集通道的点位  的操作类
   * @param electricFieldService            场站的信息
   */
  public EquipmentDataTemplateService(EquipmentDataTemplateRepository equipmentDataTemplateRepository, TemplatePointService templatePointService, EquipmentAttributeService equipmentAttributeService, ProtocolGatherDataPointService protocolGatherDataPointService, ElectricFieldService electricFieldService) {
    this.equipmentDataTemplateRepository = equipmentDataTemplateRepository;
    this.templatePointService = templatePointService;
    this.equipmentAttributeService = equipmentAttributeService;
    this.protocolGatherDataPointService = protocolGatherDataPointService;
    this.electricFieldService = electricFieldService;
  }

  /**
   * 获取所有的模版信息
   *
   * @return EquipmentDataTemplate list
   */
  public List<EquipmentDataTemplate> getAll() {
    return equipmentDataTemplateRepository.findAll();
  }

  /**
   * 存储 或者修改模版
   *
   * @param equipmentDataTemplate 模版实体
   * @return 模版实体
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public EquipmentDataTemplate saveOrUpdate(EquipmentDataTemplate equipmentDataTemplate) {
    if (equipmentDataTemplate.getId() == null) {
      //创建 模版
      EquipmentAttribute equipmentAttribute = new EquipmentAttribute();
      equipmentAttribute.setEquipmentType(equipmentDataTemplate.getTemplateType());
      equipmentDataTemplate.setStationCode(electricFieldService.get().getStationCode());
      equipmentDataTemplateRepository.save(equipmentDataTemplate);
      TemplatePoint templatePoint;
      List<EquipmentAttribute> equipmentAttributes = equipmentAttributeService.get(equipmentAttribute);
      List<TemplatePoint> templatePoints = new ArrayList<>();
      int i = 1;
      for (EquipmentAttribute e : equipmentAttributes) {
        templatePoint = new TemplatePoint();
        templatePoint.setStationCode(electricFieldService.get().getStationCode());
        templatePoint.setSequence(i++);
        templatePoint.setDataSource(DataSourceEnum.GATHER);
        templatePoint.setEquipmentDataTemplateId(equipmentDataTemplate.getId());
        templatePoint.setIsUsing(false);
        templatePoint.setEquipmentAttribute(e);
        templatePoints.add(templatePoint);
      }
      //存入模版点表
      templatePointService.addAll(templatePoints);
    } else {
      //修改
      equipmentDataTemplateRepository.save(equipmentDataTemplate);
      templatePointService.updateTunnelByTemplateId(equipmentDataTemplate.getDefaultTunnelId(), equipmentDataTemplate.getId());
    }
    return equipmentDataTemplate;
  }


  /**
   * 获取所有的模版信息
   *
   * @param equipmentDataTemplate 设备数据模版
   * @return 模版实体 list
   */
  public List<EquipmentDataTemplate> get(EquipmentDataTemplate equipmentDataTemplate) {
    if (equipmentDataTemplate == null) {
      return equipmentDataTemplateRepository.findAll();
    }
    return equipmentDataTemplateRepository.findAll(Example.of(equipmentDataTemplate));
  }


  /**
   * 根据模版id删除模版
   *
   * @param equipmentDataTemplateId 设备模版ID
   */
  @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
  public void delete(Integer equipmentDataTemplateId) {
    TemplatePoint templatePoint = new TemplatePoint();
    templatePoint.setEquipmentDataTemplateId(equipmentDataTemplateId);
    templatePointService.delete(templatePoint);
    equipmentDataTemplateRepository.deleteById(equipmentDataTemplateId);
  }


  /**
   * 通过模版生成数据点位
   *
   * @param equipmentDataTemplateId 模版id
   * @param selectedEquipment       要生成点位的设备id
   * @param findAddressN            设备的寻址位N
   */
  @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
  public void generatePoint4Equipment(int equipmentDataTemplateId, List<Integer> selectedEquipment, int findAddressN) throws BusinessException {
    EquipmentDataTemplate equipmentDataTemplate = equipmentDataTemplateRepository.findById(equipmentDataTemplateId).get();
    List<ProtocolGatherDataPoint> dataPoints;
    //删除设备原有的点位
    for (int i : selectedEquipment) {
      dataPoints = protocolGatherDataPointService.getByEquipmentId(i, equipmentDataTemplate.getTemplateType());
      if (dataPoints.size() > 0) {
        dataPoints.forEach((o) -> protocolGatherDataPointService.deleteById(o.getId()));
      }
    }
    //向点表中插入设备关联的数据
    TemplatePoint templatePoint = new TemplatePoint();
    templatePoint.setMagnification(null);
    templatePoint.setEquipmentDataTemplateId(equipmentDataTemplateId);
    List<TemplatePoint> templatePoints = templatePointService.get(templatePoint);
    templatePoints.sort(Comparator.comparingInt(TemplatePoint::getSequence));
    ProtocolGatherDataPoint protocolGatherDataPoint = null;
    for (int i : selectedEquipment) {
      for (TemplatePoint t : templatePoints) {
        if (t.getIsUsing()) {
          if (DataSourceEnum.GATHER.equals(t.getDataSource())) {
            protocolGatherDataPoint = t.turnGatherDataPoint(findAddressN);
            protocolGatherDataPoint.setEquipmentId(i);
          } else if (DataSourceEnum.GENERATE.equals(t.getDataSource())) {
            protocolGatherDataPoint = t.turnGenerateDataPoint(i);
          }
          try {
            protocolGatherDataPointService.save(protocolGatherDataPoint);
          } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BusinessException("生成点位失败，存在通道和点位同时相同的情况");
          }
        }
      }
      findAddressN++;
    }
  }


}
