package com.ho.flow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ho.business.entity.DeviceTypeCol;
import com.ho.business.entity.DeviceTypeConfig;
import com.ho.business.vo.DeviceTypeList;
import com.ho.business.vo.req.device.DeviceTypeQuery;
import com.ho.business.vo.req.deviceModel.SynchronousReqVo;
import com.ho.business.vo.req.deviceTypeCol.DeviceTypeColQueryVo;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.util.PageResult;
import com.ho.common.tools.util.PageUtils;
import com.ho.flow.feignclient.BusinessFeignClient;
import com.ho.flow.mapper.AlarmConfigMapper;
import com.ho.flow.mapper.DeviceColDefineMapper;
import com.ho.flow.service.AlarmConfigService;
import com.ho.flow.service.DeviceColDefineService;
import com.ho.flow.vo.AlarmConfig;
import com.ho.flow.vo.DeviceColDefine;
import com.ho.flow.vo.req.AlarmConfig.AlarmConfigPageReqVo;
import com.ho.flow.vo.req.AlarmConfig.DeviceColDefineReqVo;
import com.ho.flow.vo.req.devicecoldefine.DeviceColDefineDeleteVO;
import com.ho.flow.vo.req.devicecoldefine.DeviceColDefineModifyVO;
import com.ho.flow.vo.req.devicecoldefine.DeviceColDefineReqVO;
import com.ho.flow.vo.req.devicecoldefine.DeviceColDefineSyncVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author gyan
 * @desc:
 * @DateTime: 2023/2/1 16:45
 */
@Service
@Slf4j
public class DeviceColDefineServiceImpl implements DeviceColDefineService {
    @Autowired
    DeviceColDefineMapper deviceColDefineMapper;

    @Autowired
    BusinessFeignClient businessFeignClient;

    @Autowired
    AlarmConfigMapper alarmConfigMapper;

    @Autowired
    AlarmConfigService alarmConfigService;

    @Override
    public PageResult<DeviceColDefine> selectPage(DeviceColDefineReqVo definePageReq) {
        PageHelper.startPage(definePageReq.getPageNum(), definePageReq.getPageSize());
        List<DeviceColDefine> deviceColDefinePageResult = deviceColDefineMapper.selectPage(definePageReq);
        PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(deviceColDefinePageResult));
        return pageResult;

    }

    @Override
    public DeviceColDefine selectByColAndDeviceType(String Col, String deviceType) {
        DeviceColDefine deviceColDefine = deviceColDefineMapper.selectByColAndDeviceType(Col, deviceType);
        return deviceColDefine;
    }

    @Override
    public List<DeviceColDefine> selectList(DeviceColDefineReqVo definePageReq) {
        List<DeviceColDefine> list = deviceColDefineMapper.selectPage(definePageReq);
        return list;
    }

    @Override
    public DeviceColDefine selectById(Integer id) {
        DeviceColDefine deviceColDefine = deviceColDefineMapper.selectById(id);
        return deviceColDefine;
    }

    @Override
    public List<DeviceColDefine> selectByIdList(List<Integer> ids, String deviceType) {
        List<DeviceColDefine> deviceColDefines = deviceColDefineMapper.selectByIdList(ids, deviceType);
        return deviceColDefines;
    }

    public DeviceColDefineServiceImpl() {
        super();
    }

    @Override
    public DeviceColDefine selectByIdAndDeviceTypeId(Integer id, Integer deviceTypeId) {
        DeviceColDefine deviceColDefine = deviceColDefineMapper.selectByIdAndDeviceTypeId(id, deviceTypeId);
        return deviceColDefine;
    }

    @Override
    public int insertList(List<DeviceColDefineReqVO> list) {
        //以deviceType分组
        DeviceColDefine deviceCol = null;
        Map<Integer, List<DeviceColDefine>> addMap = new HashMap<>();
        Map<Integer, List<DeviceColDefine>> updateMap = new HashMap<>();
        List<DeviceColDefine> addList = new ArrayList<>();
        List<DeviceColDefine> updateList = new ArrayList<>();
        Integer num = 1;
        Integer updateNum = 1;
        Map<String, List<DeviceColDefineReqVO>> deviceMap = list.stream().collect(Collectors.groupingBy(DeviceColDefineReqVO::getDeviceType));
        List<String> deviceTypeList = deviceMap.keySet().stream().collect(Collectors.toList());
        DeviceColDefineReqVo vo = new DeviceColDefineReqVo();
        vo.setDeviceTypeList(deviceTypeList);
        List<DeviceColDefine> deviceColDefines = deviceColDefineMapper.selectPage(vo);
        Map<String, DeviceColDefine> isSaveMap = deviceColDefines.stream().collect(Collectors.toMap(i -> i.getDeviceType() + "_" + i.getCol(), deviceColDefine -> deviceColDefine));
        for (DeviceColDefineReqVO deviceColDefineReqVO : list) {
            deviceCol = isSaveMap.get(deviceColDefineReqVO.getDeviceType() + "_" + deviceColDefineReqVO.getCol());
            //走更新
            if (null != deviceCol) {
                BeanUtil.copyProperties(deviceColDefineReqVO, deviceCol);
                updateList.add(deviceCol);
                if (updateList.size() % 999 == 998) {
                    updateList = new ArrayList<>();
                    updateNum++;
                }
                updateMap.put(updateNum, updateList);
            } else {
                //走新增
                deviceCol = new DeviceColDefine();
                BeanUtil.copyProperties(deviceColDefineReqVO, deviceCol);
                addList.add(deviceCol);
                if (addList.size() % 999 == 998) {
                    addList = new ArrayList<>();
                    num++;
                }
                addMap.put(num, addList);
            }
        }
        for (Map.Entry<Integer, List<DeviceColDefine>> m : addMap.entrySet()) {
            deviceColDefineMapper.insertList(m.getValue());
        }
        for (Map.Entry<Integer, List<DeviceColDefine>> m : updateMap.entrySet()) {
            deviceColDefineMapper.updateList(m.getValue());
        }

        return 0;
    }

    @Override
    public int addDeviceColDefine(DeviceColDefineReqVO vo) {
        DeviceColDefine deviceCol = new DeviceColDefine();
        BeanUtil.copyProperties(vo, deviceCol);
        DeviceColDefineReqVo definePageReq = new DeviceColDefineReqVo();
        definePageReq.setCol(vo.getCol());
        definePageReq.setDeviceType(vo.getDeviceType());
        List<DeviceColDefine> list = deviceColDefineMapper.selectPage(definePageReq);
        if (list.size() > 0) {
            throw new BusinessException(BaseResponseCode.STATION_ALREADY_EXISTS);
        }
        return deviceColDefineMapper.insertDeviceColDefine(deviceCol);
    }

    @Override
    public int modifyDeviceColDefine(DeviceColDefineModifyVO vo) {
        DeviceColDefine deviceCol = new DeviceColDefine();
        BeanUtil.copyProperties(vo, deviceCol);
        return deviceColDefineMapper.updateDeviceColDefine(deviceCol);
    }

    @Override
    public int deleteDeviceColDefine(DeviceColDefineDeleteVO vo) {
        int count = deviceColDefineMapper.deleteDeviceColDefine(vo.getIdList());
        return count;
    }

    @Override
    public int syncNewDeviceColDefine(SynchronousReqVo vo) {
        String str = null;
        String newStr = null;
        List<DeviceColDefine> deviceColDefines = new ArrayList<>();
        if (vo.getDeviceType() != null) {
            str = vo.getDeviceType() + "_" + vo.getModelStationId();
            newStr = vo.getDeviceType() + "_" + vo.getStationId();
            DeviceColDefineReqVo definePageReq = new DeviceColDefineReqVo();
            definePageReq.setDeviceType(str);
            deviceColDefines = deviceColDefineMapper.selectPage(definePageReq);
        } else {
            deviceColDefines = deviceColDefineMapper.selectByDeviceType(CommonConstant.JOIN_STATION_ID+vo.getModelStationId());

        }
        List<DeviceColDefine> stationList = deviceColDefineMapper.selectByDeviceType(CommonConstant.JOIN_STATION_ID+vo.getStationId());
        if (deviceColDefines.size() > 0) {
            for (DeviceColDefine deviceColDefine : deviceColDefines) {
                if (newStr == null) {
                    String newDeviceType = deviceColDefine.getDeviceType();
                    int index = newDeviceType.lastIndexOf("_");
                    deviceColDefine.setDeviceType(newDeviceType.substring(0, index + 1) + vo.getStationId());
                } else {
                    deviceColDefine.setDeviceType(newStr);
                }
            }
            if (!stationList.isEmpty()) {
                List<Integer> ids = stationList.stream().map(DeviceColDefine::getId).collect(Collectors.toList());
                deviceColDefineMapper.deleteDeviceColDefine(ids);
            }
            deviceColDefineMapper.insertList(deviceColDefines);
        }
        return 0;
    }

    @Override
    public int syncDeviceColDefine(DeviceColDefineSyncVO definePageReq) {
        DeviceTypeColQueryVo vo = new DeviceTypeColQueryVo();
        vo.setDeviceType(definePageReq.getDeviceType());
        vo.setStationId(definePageReq.getStationId());
        List<DeviceTypeCol> deviceTypeCols = businessFeignClient.selectDeviceTypeCol(vo);

        List<DeviceColDefineReqVO> list = new ArrayList<>();
        DeviceColDefineReqVO dcd = null;
        for (DeviceTypeCol deviceTypeCol : deviceTypeCols) {
            dcd = new DeviceColDefineReqVO();
            dcd.setDeviceName(deviceTypeCol.getDeviceTypeName());
            dcd.setDeviceType(deviceTypeCol.getDeviceType());
            dcd.setCol(deviceTypeCol.getCol());
            dcd.setColEn(deviceTypeCol.getColEn());
            dcd.setColName(deviceTypeCol.getColName());
            dcd.setSensType(deviceTypeCol.getSensType());
            //若是遥信
            if (CommonConstant.ONE.equals(deviceTypeCol.getSensType())) {
                dcd.setInfo0(deviceTypeCol.getColName() + CommonConstant.Info.QUANTILE);
                dcd.setInfo1(deviceTypeCol.getColName() + CommonConstant.Info.CLOSED_POSITION);
            }
            list.add(dcd);
        }
        if (list.size() > 0) {
            insertList(list);
        }
        return 0;
    }


    @Override
    public int deviceColDefine(List<DeviceTypeCol> deviceTypeCols) {
        try {
            List<DeviceColDefineReqVO> list = new ArrayList<>();
            DeviceColDefineReqVO dcd = null;
            for (DeviceTypeCol deviceTypeCol : deviceTypeCols) {
                dcd = new DeviceColDefineReqVO();
                dcd.setDeviceName(deviceTypeCol.getDeviceTypeName());
                dcd.setDeviceType(deviceTypeCol.getDeviceType());
                dcd.setCol(deviceTypeCol.getCol());
                dcd.setColName(deviceTypeCol.getColName());
                dcd.setSensType(deviceTypeCol.getSensType());
                //若是遥信
                if (CommonConstant.ONE.equals(deviceTypeCol.getSensType())) {
                    dcd.setInfo0(deviceTypeCol.getColName() + CommonConstant.Info.QUANTILE);
                    dcd.setInfo1(deviceTypeCol.getColName() + CommonConstant.Info.CLOSED_POSITION);
                }
                list.add(dcd);
            }
            if (list.size() > 0) {
                insertList(list);
            }
        } catch (Exception e) {
            log.error("同步告警配置,{}", e.getMessage());
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public void syncAlarmConfigList(DeviceTypeList deviceTypeList) {
        try {
            List<DeviceTypeCol> deviceTypeCols = deviceTypeList.getList();
            Map<String, List<DeviceTypeCol>> collect = deviceTypeCols.stream().collect(Collectors.groupingBy(i -> i.getDeviceType()));
            String deviceType = deviceTypeCols.get(0).getDeviceType();
            int i = deviceType.lastIndexOf("_");
            String stationIdValue = deviceType.substring(i + 1, deviceType.length());
            Integer stationId = Integer.valueOf(stationIdValue);
            Set<String> keySet = collect.keySet();
            List<String> typeList = keySet.stream().collect(Collectors.toList());
            //获取已配置告警
            AlarmConfigPageReqVo vo = new AlarmConfigPageReqVo();
            vo.setScope(CommonConstant.TWO);
            vo.setStationId(stationId);
            vo.setDeviceTypeList(typeList);
            List<AlarmConfig> configList = alarmConfigService.selectList(vo);
            Map<String, AlarmConfig> configMap = configList.stream().collect(Collectors.toMap(k -> k.getDeviceType() + "_" + k.getCol(), Function.identity(), (k1, k2) -> k2));
            //获取告警定义
            DeviceColDefineReqVo defineReqVo = new DeviceColDefineReqVo();
            defineReqVo.setDeviceTypeList(typeList);
            List<DeviceColDefine> colDefineList = selectList(defineReqVo);
            Map<String, DeviceColDefine> colDefineMap = colDefineList.stream().collect(Collectors.toMap(k -> k.getDeviceType() + "_" + k.getCol(), Function.identity(), (k1, k2) -> k2));

            List<AlarmConfig> addList = new ArrayList<>();
            List<AlarmConfig> updateList = new ArrayList<>();
            DeviceColDefine deviceColDefine = null;
            Date now = new Date();
            for (DeviceTypeCol deviceTypeCol : deviceTypeCols) {
                AlarmConfig alarm = configMap.get(deviceTypeCol.getDeviceType() + "_" + deviceTypeCol.getCol());
                deviceColDefine = colDefineMap.get(deviceTypeCol.getDeviceType() + "_" + deviceTypeCol.getCol());
                if (null == alarm) {
                    alarm = new AlarmConfig();
                    alarm.setGroupId(deviceTypeList.getGroupId());
                    alarm.setStationId(stationId);
                    alarm.setScope(CommonConstant.TWO);
                    alarm.setColDefineId(deviceColDefine.getId());
                    alarm.setDeviceTypeId(deviceColDefine.getDeviceTypeId());
                    alarm.setDeviceName(deviceColDefine.getDeviceName());
                    alarm.setDeviceType(deviceColDefine.getDeviceType());
                    alarm.setCol(deviceColDefine.getCol());
                    alarm.setColName(deviceColDefine.getColName());
                    alarm.setSensType(deviceColDefine.getSensType());
                    alarm.setInfo0(deviceColDefine.getInfo0());
                    alarm.setInfo1(deviceColDefine.getInfo1());
                    alarm.setAlarmLevel(deviceTypeCol.getAlarmLevel());
                    alarm.setCreateTime(now);
                    alarm.setDeleted(CommonConstant.ONE);
                    addList.add(alarm);
                } else {
                    alarm.setDeviceName(deviceTypeCol.getDeviceTypeName());
                    alarm.setInfo0(deviceColDefine.getInfo0());
                    alarm.setInfo1(deviceColDefine.getInfo1());
                    alarm.setAlarmLevel(deviceTypeCol.getAlarmLevel());
                    alarm.setUpperLimit(deviceTypeCol.getMaxValue());
                    alarm.setLowerLimit(deviceTypeCol.getMinValue());
                    alarm.setUpdateTime(now);
                    updateList.add(alarm);
                }
            }
            if (addList.size() > 0) {
                alarmConfigMapper.insertBatch(addList);
            }
            if (updateList.size() > 0) {
                alarmConfigMapper.updateBatch(updateList);
            }
        } catch (Exception e) {
            log.error("同步告警数据,{}", e.getMessage());
            e.printStackTrace();
        }
    }
}
