package com.zd.laboratory.service.impl;

import cn.hutool.core.util.StrUtil;
import com.zd.common.core.constant.CacheConstants;
import com.zd.common.core.constant.CacheDevice;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.enums.SenseStateEnum;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.redis.service.RedisService;
import com.zd.common.security.utils.SaveUtil;
import com.zd.laboratory.config.HardwareFunctionStatusConfig;
import com.zd.laboratory.domain.LabHardware;
import com.zd.laboratory.domain.LabSensor;
import com.zd.laboratory.domain.vo.LabSensorVO;
import com.zd.laboratory.mapper.LabSensorMapper;
import com.zd.laboratory.service.ILabSensorService;
import com.zd.system.api.laboratory.domain.SensorFunctionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 传感器Service业务层处理
 *
 * @author zd
 * @date 2021-08-30
 */
@Service
public class LabSensorServiceImpl implements ILabSensorService {
    private static Logger logger = LoggerFactory.getLogger(LabSensorServiceImpl.class);
    @Autowired
    private LabSensorMapper labSensorMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    public HardwareFunctionStatusConfig hardwareFunctionStatusConfig;

    /**
     * 查询传感器
     *
     * @param id 传感器主键
     * @return 传感器
     */
    @Override
    public LabSensor selectLabSensorById(Long id) {
        return labSensorMapper.selectLabSensorById(id);
    }



    /**
     * 查询实验室返回传感器数量
     *
     * @param subjectId 实验室id
     * @return 传感器
     */
    @Override
    public int selectSensorCountBySubIds(Long subjectId) {
        int countNum=labSensorMapper.selectSensorCountBySubIds(subjectId);
        return countNum;
    }


    /**
     * 查询传感器列表
     *
     * @param labSensor 传感器
     * @return 传感器
     */
    @Override
    @DataScope(deptAlias = "xx", userAlias = "xx", permi = PerPrefix.LABORATORY_SENSOR)
    public List<LabSensorVO> selectLabSensorList(LabSensor labSensor) {
//        Long subjectId=null;
//        Collection<String> a = redisService.keys(CacheConstants.SENSOR_KEY + "*");
//        Collection<String> sensorData = redisService.keys(CacheConstants.SENSOR_DATA_KEY_ISONLINE + "*");;
//        List<String> gatewayIds = new ArrayList<>();
//        List<String> senorIdList = new ArrayList<>();
//        for (String s : a) {
//            gatewayIds.add(s.replace(CacheConstants.SENSOR_KEY, ""));
//        }
//        for (String s : sensorData) {
//            String key=s.replace(CacheConstants.SENSOR_DATA_KEY_ISONLINE, "");
//            String[] keys=key.split(",");
//            if(null==subjectId){
//                subjectId=Long.parseLong(keys[1]);
//            }
//            senorIdList.add(keys[0]);
//        }
//        int countNum=labSensorMapper.selectSensorCountBySubIds(subjectId);
//        if(gatewayIds.size() > 0){
//            labSensorMapper.updateStateByGatewayIds(gatewayIds, SenseStateEnum.TURN_ON.getCode());
//        }else{
//            labSensorMapper.updateStateOther(gatewayIds, SenseStateEnum.OFFLINE.getCode());
//        }
//        if(senorIdList.size()>0){
//            labSensorMapper.updateStateBySenorIds(senorIdList,SenseStateEnum.TURN_ON.getCode());
//        }
//        if(countNum!=senorIdList.size()){
//            labSensorMapper.updateStateBySenorNotIds(senorIdList,subjectId,SenseStateEnum.OFFLINE.getCode());
//        }
        List<LabSensorVO> data = labSensorMapper.selectLabSensorList(labSensor);
        /*data.stream().forEach(d -> {
            if(d.getGatewayId()!= null && redisService.hasKey(CacheConstants.SENSOR_KEY + d.getGatewayId())){
                d.setSenseState(SenseStateEnum.TURN_ON);
            }else {
                d.setSenseState(SenseStateEnum.OFFLINE);
            }
        });*/
        return data;
    }


    /**
     * 查询传感器列表
     *
     * @param labSensor 传感器
     * @return 传感器
     */
    @Override
    @DataScope(deptAlias = "xx", userAlias = "xx", permi = PerPrefix.LABORATORY_SENSOR)
    public List<LabSensorVO> selectLabSensorList(LabSensor labSensor,int countNum,Long subjectId) {
        Collection<String> a = redisService.keys(CacheDevice.SENSOR_KEY.getRedisKey() + "*");
        Collection<String> sensorData = redisService.keys(CacheConstants.SENSOR_DATA_KEY_ISONLINE + "*");;
        List<String> gatewayIds = new ArrayList<>();
        List<String> senorIdList = new ArrayList<>();
        for (String s : a) {
            gatewayIds.add(s.replace(CacheDevice.SENSOR_KEY.getRedisKey(), ""));
        }
        for (String s : sensorData) {
            String key=s.replace(CacheConstants.SENSOR_DATA_KEY_ISONLINE, "");
            String[] keys=key.split(",");
            senorIdList.add(keys[0]);
        }
        if(gatewayIds.size() > 0){
            labSensorMapper.updateStateByGatewayIds(gatewayIds, SenseStateEnum.TURN_ON.getCode());
        }else{
            labSensorMapper.updateStateOther(gatewayIds, SenseStateEnum.OFFLINE.getCode());
        }
        if(senorIdList.size()>0){
            labSensorMapper.updateStateBySenorIds(senorIdList,SenseStateEnum.TURN_ON.getCode());
        }
        if(countNum!=senorIdList.size()){
            labSensorMapper.updateStateBySenorNotIds(senorIdList,subjectId,SenseStateEnum.OFFLINE.getCode());
        }
        List<LabSensorVO> data = labSensorMapper.selectLabSensorList(labSensor);
        /*data.stream().forEach(d -> {
            if(d.getGatewayId()!= null && redisService.hasKey(CacheConstants.SENSOR_KEY + d.getGatewayId())){
                d.setSenseState(SenseStateEnum.TURN_ON);
            }else {
                d.setSenseState(SenseStateEnum.OFFLINE);
            }
        });*/
        return data;
    }


    /**
     * 新增传感器
     *
     * @param labSensor 传感器
     * @return 结果
     */
    @Override
    public int insertLabSensor(LabSensor labSensor) {
        SaveUtil.setCommonAttr(labSensor);
        return labSensorMapper.insertLabSensor(labSensor);
    }

    /**
     * 根据网关编码获取实验室ID
     * @param GatewayNum
     * @return
     */
    @Override
    public Long getCacheSubByGateway(String GatewayNum) {
        if(StrUtil.isEmpty(GatewayNum)) return null;
        Object subjectStr=redisService.getCacheObject(getKey(GatewayNum));
        Long subId=null;
        if(null!=subjectStr && !"".equals(subjectStr) ){
            logger.error("num:"+GatewayNum+"subjectStr:"+subjectStr);
            subId=Long.parseLong(subjectStr.toString());
        }

        //todo 当前单机部署不需要考虑， 否则要放开下部分代码
//        if(subId==null)
//        {
        //这里存在分布式问题
//            //超时时间设置为20秒
//            if(redisService.redisTemplate.opsForValue().setIfAbsent(getKey(GatewayNum+":cacheset"),true,20,TimeUnit.SECONDS))
//            {
//
//                LabSensor labSensor = new LabSensor();
//                labSensor.setGatewayId(GatewayNum);
//                List<LabSensorVO> labSensorVOS = selectLabSensorList(labSensor);
//                Long aLong = Optional.ofNullable(labSensorVOS)
//                        .filter(a -> a.size() > 0)
//                        .map(a -> a.get(0))
//                        .map(a -> a.getSubjectId())
//                        .orElse(null);
//                if(aLong!=null)
//                {
//                    redisService.setCacheObject(getKey(GatewayNum),aLong);
//                }
//                return aLong;
//            }
//            else
//            {
//                //随眠50毫秒
//                Thread.sleep(100);
//                getCacheSubByGateway(GatewayNum);
//            }
//
//
//        }
        //后来仔细想了一下， socket 可能存在并行， 这里还是最好改造下
        if(subId==null)
        {
            LabSensor labSensor = new LabSensor();
            labSensor.setGatewayId(GatewayNum);
            List<LabSensorVO> labSensorVOS = labSensorMapper.selectLabSensorList(labSensor);
            Long aLong = Optional.ofNullable(labSensorVOS)
                    .filter(a -> a.size() > 0)
                    .map(a -> a.get(0))
                    .map(a -> a.getSubjectId())
                    .orElse(null);
            if(null==aLong){
                List<LabHardware> labHardwares=labSensorMapper.selectHardWareList(GatewayNum);
                aLong = Optional.ofNullable(labHardwares)
                        .filter(a -> a.size() > 0)
                        .map(a -> a.get(0))
                        .map(a -> a.getSubjectId())
                        .orElse(null);
            }
            subId=aLong;
            redisService.setCacheObject(getKey(GatewayNum),aLong,5L, TimeUnit.MINUTES);
        }
        logger.error("num:"+GatewayNum+"subId:"+subId);
        return subId;
    }


    /**
     * 修改传感器
     *
     * @param labSensor 传感器
     * @return 结果
     */
    @Override
    public int updateLabSensor(LabSensor labSensor) {
        labSensor.setUpdateTime(DateUtils.getNowDate());



        LabSensor old = labSensorMapper.selectLabSensorById(labSensor.getId());
        int i = labSensorMapper.updateLabSensor(labSensor);
        if(i==1)
        //需要删除旧的key
        {
            if(old.getGatewayId()!=null)
            {
                redisService.deleteObject(getKey(old.getGatewayId()));
            }
        }
        return i;
    }
    private String getKey(String gatewayId) {
        return CacheConstants.GATEWAY_KEY+ gatewayId;
    }

    /**
     * 批量删除传感器
     *
     * @param ids 需要删除的传感器主键
     * @return 结果
     */
    @Override
    public int deleteLabSensorByIds(Long[] ids) {
        //删除网管缓存
        List<LabSensorVO> labSensorVOS = labSensorMapper.selectLabSensorListByIds(ids);
        Optional.ofNullable(labSensorVOS)
                .filter(a->a.size()>0)
                .orElse(Collections.emptyList())
                .stream().filter(a->a.getGatewayId()!=null)
                .forEach(a->{
                    redisService.deleteObject(getKey(a.getGatewayId()));
                });

        return labSensorMapper.deleteLabSensorByIds(ids);
    }

    /**
     * 删除传感器信息
     *
     * @param id 传感器主键
     * @return 结果
     */
    @Override
    public int deleteLabSensorById(Long id) {
        return labSensorMapper.deleteLabSensorById(id);
    }

    /**
     * 查询传感器功能列表
     *
     * @return 功能集合
     */
    @Override
    public List<SensorFunctionStatus> getFunList() {
        return hardwareFunctionStatusConfig.getSensorFunctionStatuses();
    }
}
