package com.ho.business.service.impl;

import com.ho.business.entity.DeviceTypeConfig;
import com.ho.business.entity.ModelDevice;
import com.ho.business.mapper.DeviceTypeConfigMapper;
import com.ho.business.mapper.ModelTypeMapper;
import com.ho.business.service.DeviceTypeColService;
import com.ho.business.service.DeviceTypeConfigService;
import com.ho.business.vo.req.device.DeviceTypeConfigAddReq;
import com.ho.business.vo.req.device.DeviceTypeQuery;
import com.ho.business.vo.req.deviceModel.SynchronousReqVo;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.deviceTypeCol.DeviceTypeColCountResp;
import com.ho.business.vo.resp.point.DevicePointResp;
import com.ho.common.tools.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

import static cn.hutool.core.text.StrPool.UNDERLINE;

/**
 * @author fancl
 * @desc: 设备类型配置的实现类
 * @date 2023/3/18
 */
@Service
@Slf4j
public class DeviceTypeConfigServiceImpl implements DeviceTypeConfigService {

    @Autowired
    DeviceTypeConfigMapper deviceTypeConfigMapper;

    @Autowired
    DeviceTypeColService deviceTypeColService;

    @Override
    public DeviceTypeConfig queryById(Integer id) {
        DeviceTypeConfig deviceTypeConfig = deviceTypeConfigMapper.selectById(id);
        return deviceTypeConfig;
    }

    @Override
    public List<DeviceTypeConfig> queryListByCondition(DeviceTypeQuery deviceTypeQuery) {
        List<DeviceTypeConfig> list = deviceTypeConfigMapper.selectListByCondition(deviceTypeQuery);
        return list;
    }

    @Override
    public List<String> getStationDeviceTypes(Integer stationId) {
        //先查设备类型
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setStationId(stationId);
        deviceTypeQuery.setType("all");
        List<DeviceTypeConfig> deviceTypeConfigs = queryListByCondition(deviceTypeQuery);
        List<String> deviceTypes = new ArrayList<>();
        for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
            deviceTypes.add(deviceTypeConfig.getDeviceType());
        }
        return deviceTypes;
    }

    @Override
    public void add(DeviceTypeConfig deviceTypeConfig) {
        deviceTypeConfigMapper.add(deviceTypeConfig);
    }

    @Override
    public void updateById(DeviceTypeConfig deviceTypeConfig) {
        deviceTypeConfigMapper.update(deviceTypeConfig);
    }

    @Override
    public void deleteById(Integer id) {
        deviceTypeConfigMapper.deletedById(id);
    }

    /**
     * 根据设备类型查询设备类型配置
     *
     * @param deviceType 设备类型
     * @return
     */
    @Override
    public DeviceTypeConfig selectByDeviceType(String deviceType, Integer groupId) {
        return deviceTypeConfigMapper.selectByDeviceType(deviceType, groupId);
    }

    @Override
    public List<DeviceTypeConfig> selectByType(String deviceType, Integer stationId) {
        return deviceTypeConfigMapper.selectByType(deviceType, stationId);
    }

    @Override
    public List<DevicePointResp> getTreeDevices(List<DeviceRespVO> deviceRespVOS) {
        //转化对象
        List<DevicePointResp> pointDeviceResps = deviceRespVOS.stream().map(s -> {
            DevicePointResp devicePointResp = new DevicePointResp();
            BeanUtils.copyProperties(s, devicePointResp);
            devicePointResp.setName(s.getDeviceName());
            return devicePointResp;
        }).collect(Collectors.toList());
        //根据pid进行分组
        Map<Integer, List<DevicePointResp>> pidListMap =
                pointDeviceResps.stream().collect(Collectors.groupingBy(DevicePointResp::getPid));
        //给子集合赋值
        pointDeviceResps.stream().forEach(item -> item.setChildren(CommonConstant.ZERO.equals(item.getSrcId()) ? null : pidListMap.get(item.getSrcId())));
        //返回结果也改为返回顶层节点的list
        return pidListMap.get(0);
    }

    @Override
    public List<DevicePointResp> getTreeDevices(List<DeviceRespVO> deviceRespVOS, Integer srcId) {
        List<String> typeList = deviceRespVOS.stream().map(s->s.getDeviceType()).distinct().collect(Collectors.toList());
        List<DeviceTypeColCountResp> countRespList = deviceTypeColService.countByDeviceType(typeList);
        Map<String, Integer> typeNumMap = countRespList.stream().collect(Collectors.toMap(DeviceTypeColCountResp::getDeviceType, DeviceTypeColCountResp::getNum, (k1, k2) -> k2));
        List<DevicePointResp> pointDeviceResps = deviceRespVOS.stream().map(s -> {
            DevicePointResp pointDeviceResp = new DevicePointResp();
            BeanUtils.copyProperties(s, pointDeviceResp);
            pointDeviceResp.setName(s.getDeviceName());
            pointDeviceResp.setIsContainCol(s.getDeviceType() == null?CommonConstant.ZERO:(typeNumMap.get(s.getDeviceType()) == null?CommonConstant.ZERO:CommonConstant.ONE));
            return pointDeviceResp;
        }).collect(Collectors.toList());
        //根据pid进行分组
        Map<Integer, List<DevicePointResp>> pidListMap = pointDeviceResps.stream().collect(Collectors.groupingBy(DevicePointResp::getPid));
        //给子集合赋值
        pointDeviceResps.stream().forEach(item -> item.setChildren(pidListMap.get(item.getSrcId()) == null ? new ArrayList<>() : pidListMap.get(item.getSrcId())));
        Map<Integer, List<DevicePointResp>> srcIdListMap = pointDeviceResps.stream().collect(Collectors.groupingBy(DevicePointResp::getSrcId));
        //返回结果也改为返回顶层节点的list
        List<DevicePointResp> rootTree = pidListMap.get(0);
        if (srcId != null) {
            rootTree = srcIdListMap.get(srcId);
            List<DevicePointResp> chooseTree = pidListMap.get(srcId);
            if (!rootTree.isEmpty()) {
                rootTree.get(0).setChildren(chooseTree);
            }

        }
        return rootTree;
    }

    @Override
    public void update(DeviceTypeConfigAddReq reqVo) {
        List<DeviceTypeConfig> deviceTypeConfigs = selectByType(reqVo.getDeviceType(), reqVo.getStationId());
        for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
            String deviceTypeNew = deviceTypeConfig.getName();
            if (deviceTypeNew.contains("_")) {
                String newName = deviceTypeNew.substring(0, deviceTypeNew.indexOf("_")) + "_" + reqVo.getName();
                deviceTypeConfig.setName(newName);
                deviceTypeConfigMapper.update(deviceTypeConfig);
            }
        }
    }

    @Override
    public int syDeviceTypeConfig(SynchronousReqVo vo) {
        //源电站id
        Integer srcStationId = vo.getModelStationId();
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setStationId(srcStationId);
        List<DeviceTypeConfig> deviceTypeConfigList = queryListByCondition(deviceTypeQuery);
        List<DeviceTypeConfig> desList = new ArrayList<>();
        Date now = new Date();
        for (DeviceTypeConfig deviceTypeConfig:deviceTypeConfigList) {
            DeviceTypeConfig dtc = new DeviceTypeConfig();
            BeanUtils.copyProperties(deviceTypeConfig,dtc);
            dtc.setId(null);
            dtc.setStationId(vo.getStationId());
            dtc.setDeviceType(deviceTypeConfig.getDeviceType().replace(UNDERLINE+srcStationId, UNDERLINE+vo.getStationId()));
            String[] names = dtc.getName().split(UNDERLINE);
            if(names.length>1){
                String name = dtc.getName().replace(names[names.length-1],vo.getDesStationName());
                dtc.setName(name);
            }
            dtc.setCreateTime(now);
            desList.add(dtc);
        }
        int result = 0;
        if(desList.size()>0){
            result = deviceTypeConfigMapper.deleteByStationId(vo.getStationId());
            log.info("一键同步设备类型配置删除旧设备：{}",result);
            result = deviceTypeConfigMapper.addBatchDeviceTypeConfig(desList);
        }
        log.info("一键同步设备类型配置,匹配到数据：{}，result：{}",desList.size(),result);
        result = syModelDevice(vo);
        log.info("一键同步模型类型配置，result：{}",result);
        return result;
    }

    @Override
    public void updateDeviceTypeConfigList(List<DeviceTypeConfig> list) {
        int count = deviceTypeConfigMapper.updateDeviceTypeConfigList(list);
        log.info("批量更新设备类型：{}",count);
    }

    @Autowired
    ModelTypeMapper modelTypeMapper;

    /**
     * 同步模型类型配置
     * @param vo
     * @return
     */
    private int syModelDevice(SynchronousReqVo vo){
        int result = 0;
        List<ModelDevice> modelDevices = modelTypeMapper.selectByDeviceType(UNDERLINE + vo.getModelStationId());
        if(!modelDevices.isEmpty()){
            List<ModelDevice> insertList = new ArrayList<>();
            ModelDevice modelDevice = null;
            for (ModelDevice md:modelDevices) {
                modelDevice = new ModelDevice();
                modelDevice.setModelType(md.getModelType());
                modelDevice.setDeviceType(md.getDeviceType().replace(UNDERLINE+vo.getModelStationId(), UNDERLINE+vo.getStationId()));
                insertList.add(modelDevice);
            }
            if(!insertList.isEmpty()){
                result = modelTypeMapper.deleteModelDeviceByDeviceType(UNDERLINE + vo.getStationId());
                log.info("一键同步设备类型配置删除旧设备：{}",result);
                result = modelTypeMapper.insertModelDeviceList(insertList);
            }
        }
        return result;
    }
}
