package com.ho.business.service.impl;


import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.*;
import com.ho.business.mapper.DeviceTypeMapper;
import com.ho.business.mapper.TopologyMapper;
import com.ho.business.mapper.TypeContrastMapper;
import com.ho.business.service.TopologyService;
import com.ho.business.vo.req.TopologyInReqVo;
import com.ho.business.vo.req.TopologyReqVo;
import com.ho.business.vo.req.TopologyType;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yule
 * @description 针对表【topology】的数据库操作Service实现
 * @createDate 2022-08-25 16:06:40
 */
@Service
@Slf4j
public class TopologyServiceImpl implements TopologyService {

    @Autowired
    TopologyMapper topologyMapper;

    @Autowired
    TypeContrastMapper typeContrastMapper;

    @Autowired
    DeviceTypeMapper deviceTypeMapper;

    @Override
    public String findDeviceType(Integer stationId, Integer srcId) {
        TopologyQuery topologyQuery = new TopologyQuery();
        topologyQuery.setStationId(stationId);
        topologyQuery.setSrcId(srcId);
        Topology topology = topologyMapper.selectOne(topologyQuery);
        TypeContrast typeContrast = typeContrastMapper.getDeviceTypeId(topology);
        if (typeContrast == null) {
            return null;
        }
        DeviceType deviceType = deviceTypeMapper.getDeviceType(typeContrast.getDeviceTypeId());
        if (deviceType == null) {
            return null;
        }
        return deviceType.getDeviceType();
    }

    @Override
    public DeviceType findDeviceTypeOne(Integer stationId, Integer srcId) {
        TopologyQuery topologyQuery = new TopologyQuery();
        topologyQuery.setStationId(stationId);
        topologyQuery.setSrcId(srcId);
        Topology topology = topologyMapper.selectOne(topologyQuery);
        TypeContrast typeContrast = typeContrastMapper.getDeviceTypeId(topology);
        if (typeContrast == null) {
            return null;
        }
        DeviceType deviceType = deviceTypeMapper.getDeviceType(typeContrast.getDeviceTypeId());
        if (deviceType == null) {
            return null;
        }
        return deviceType;
    }

    @Override
    public void deleteBytopologyId(Integer id) {
        topologyMapper.deleteBytopologyId(id);

    }

    @Override
    public int insertSelective(Topology record) {
        int i = topologyMapper.insertSelective(record);
        return i;
    }

    @Override
    public Topology selectByPrimaryKey(Integer id) {
        Topology topology = topologyMapper.selectByPrimaryKey(id);
        return topology;
    }

    @Override
    public Topology selectOne(TopologyQuery topologyQuery) {
        List<Topology> topologies = topologyMapper.selectList(topologyQuery);
        if (topologies.isEmpty() || topologies == null) {
            return null;
        }
        return topologies.get(0);
    }

    @Override
    public List<Topology> selectList(TopologyQuery topologyQuery) {
        List<Topology> topologies = topologyMapper.selectList(topologyQuery);
        return topologies;
    }

    @Override
    public List<Topology> selectByStationId(Integer id) {
        List<Topology> topologyList = topologyMapper.selectByStationId(id);
        if (!topologyList.isEmpty()) {
            for (Topology topology : topologyList) {
                String deviceType = findDeviceType(topology.getStationId(), topology.getSrcId());
                topology.setMonitorType(deviceType);
            }
        }
        return topologyList;
    }

    //更新
    @Override
    public int updateByPrimaryKeySelective(TopologyInReqVo vo) {
        return topologyMapper.updateByPrimaryKeySelective(vo);
    }

    @Override
    public int updateByPrimaryKey(Topology vo) {
        int i = topologyMapper.updateByPrimaryKey(vo);
        return i;
    }


    //根据名字查询
    @Override
    public Topology selectBysev(TopologyReqVo vo) {
        Topology topology = topologyMapper.selectBysev(vo);
        return topology;
    }


    //查询电站的拓扑数据
    @Override
    public Topology selectByStation(Integer stationId, Integer deptId, Integer groupId) {
        Topology topologyList = topologyMapper.selectByStation(stationId, deptId, groupId);
        return topologyList;
    }


    //查询舱数据
    @Override
    public List<Topology> selectByWarehouse(Integer srcId) {
        List<Topology> topologyList = topologyMapper.selectByWarehouse(srcId);
        if (topologyList == null) {
            throw new BusinessException(BaseResponseCode.WAREHOUSE_NOT_EXISTS);
        }
        return topologyList;
    }

    //查询堆拓扑
    @Override
    public List<Topology> selectByStack(Integer srcId) {
        List<Topology> topologyList = topologyMapper.selectByStack(srcId);
        return topologyList;
    }

    @Override
    public List<Topology> selectByType(TopologyType topologyType, List<Station> list) {
        Topology topology = null;
        if (topologyType.getType() != null) {
            topology = DeviceTypeConstant.getDeviceType(topologyType.getType());
        }
        TopologyQuery topologyQuery = new TopologyQuery();
        if (topology.getCategory() == null) {
            return new ArrayList<>();
        }
        if (topology.getCategory() != null) {
            topologyQuery.setCategory(topology.getCategory());
        }
        if (topology.getType() != null) {
            topologyQuery.setType(topology.getType());
        }
        if (topology.getSubType() != null) {
            topologyQuery.setSubType(topology.getSubType());
        }
        List<Integer> stationIds = list.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());
        topologyQuery.setStationIds(stationIds);
        List<Topology> topologyList = topologyMapper.selectList(topologyQuery);
        List<Topology> tops = new ArrayList<>();
        //topologyList 按照电站id过滤
        for (Integer stationId : stationIds) {
            List<Topology> stationTopos = topologyList.stream().filter(tp -> stationId.equals(tp.getStationId())).collect(Collectors.toList());
            if (stationTopos != null && !stationTopos.isEmpty()) {
                //将返回的数据都追加到list中
                tops.addAll(getTops(stationTopos, new ArrayList<>()));
            }
        }

        //查上一级数据
        //因为有多个电站的情况,所以以电站去给 topologyList 过滤
        //topologyList
        //topologyList = getTops(topologyList, new ArrayList<>());

        for (Topology topologyFor : tops) {
            String deviceType = findDeviceType(topologyFor.getStationId(), topologyFor.getSrcId());
            topologyFor.setMonitorType(deviceType);
        }
        return tops;
    }

    private List<Topology> getTops(List<Topology> topologyList, List<Topology> parentTopogies) {
        Integer stationId = null;
        List<Integer> pIds = new ArrayList<>();
        //只有第一次循环的时候需要给 stationId 和pIds赋值
        if (parentTopogies.isEmpty() && !topologyList.isEmpty()) {
            stationId = topologyList.get(0).getStationId();
            for (Topology topology : topologyList) {
                pIds.add(topology.getPid());
            }
        } else {
            stationId = parentTopogies.get(0).getStationId();
            //遍历父集合
            for (Topology topology : parentTopogies) {
                if (topology.getPid() == 0) {
                    return topologyList;
                }
                pIds.add(topology.getPid());
            }
        }
        parentTopogies = topologyMapper.selectListByPid(stationId, pIds);
        topologyList.addAll(parentTopogies);
        return getTops(topologyList, parentTopogies);
    }

    /**
     * 通过设备类型和电站id获取到设备topology集合
     *
     * @param stationId  电站id
     * @param deviceType 设备类型
     * @return
     */
    @Override
    public List<Topology> getTopologies(Integer stationId, String deviceType) {
        //查询充电桩的类别与类型
        Topology chargeTopology = DeviceTypeConstant.getDeviceType(deviceType);
        //查询到topology表关于充电桩所有的topology数据
        TopologyQuery topologyQuery = new TopologyQuery();
        if (chargeTopology.getType() == null) {
            return new ArrayList<>();
        }
        topologyQuery.setCategory(chargeTopology.getCategory());
        topologyQuery.setType(chargeTopology.getType());
        if (chargeTopology.getSubType() != null) {
            topologyQuery.setSubType(chargeTopology.getSubType());
        }
        topologyQuery.setStationId(stationId);
        List<Topology> topologyList = topologyMapper.selectList(topologyQuery);

        return topologyList;
    }


    @Override
    public Topology getStationTopology(Integer stationId) {
        Topology stationTopology = topologyMapper.getStationTopology(stationId);
        return stationTopology;
    }

    @Override
    public List<Topology> getCategoryTopology(Topology topology) {
        List<Topology> bayTopology = topologyMapper.getCategoryTopology(topology);
        return bayTopology;
    }

    @Override
    public List<Topology> getTopology(Integer stationId) {
        List<Topology> topologyList = new ArrayList<>();
        //查询113
        Topology stationTopology = getStationTopology(stationId);
        if (stationTopology == null) {
            return new ArrayList<>();
        }
        topologyList.add(stationTopology);
        //查询271
        Topology topology = new Topology();
        topology.setStationId(stationId);
        topology.setCategory(2);
        topology.setType(7);
        topology.setSubType(1);
        List<Topology> bayTopology = getCategoryTopology(topology);
        topologyList.addAll(bayTopology);
        return topologyList;
    }
}
