package com.gonghang.h5clientapp.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gonghang.h5clientapp.beans.RobotData;
import com.gonghang.h5clientapp.beans.dto.*;
import com.gonghang.h5clientapp.beans.vo.*;
import com.gonghang.h5clientapp.common.RedisKey;
import com.gonghang.h5clientapp.common.enumData.EnvTypeEnum;
import com.gonghang.h5clientapp.common.enumData.TaskStatusEnum;
import com.gonghang.h5clientapp.dao.*;
import com.gonghang.h5clientapp.util.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by shiwn on 2022/7/5 9:01
 */
@Service
public class GhH5ServiceImpl implements GhH5Service {
    @Autowired
    private RobotMapper robotMapper;
    @Autowired
    private EnvDataMapper envDataMapper;
    @Autowired
    private EnvSettingService envSettingService;
    @Autowired
    private CheckTaskMapper taskMapper;
    @Autowired
    private CheckPointMapper pointMapper;
    @Autowired
    private TaskDataMapper taskDataMapper;
    @Autowired
    private RobotSettingMapper robotSettingMapper;
    @Autowired
    private TaskReportMapper reportMapper;
    @Autowired
    private RobotWarningService robotWarningService;
    @Autowired
    private MapService mapService;
    @Autowired
    RedisUtils redisUtils;

    /**
     * 全局变量，保存全部机器人
     */
    private List<GhRobotVO> listRobot = new ArrayList<>();

    /**
     * @Description: 获取机器人列表
     * @Author: shiwn
     * @Param: []
     * @Return:
     */
    @Override
    public List<GhRobotVO> getRobotList() {
        //  查询
        List<GhRobotVO> list = new ArrayList<>();
        List<RobotDTO> listDto = robotMapper.queryAllRobots();
        //  封装
        listDto.forEach(i -> {
            GhRobotVO vo = new GhRobotVO();
            vo.setRobotId(i.getId());
            vo.setRobotIp(i.getIp());
            vo.setRobotName(i.getRobotName());
            list.add(vo);
        });
        // 返回
        listRobot = list;
        return list;
    }

    /**
     * @Description: 查询机器人信息
     * @Date: 2022/7/5 11:39
     * @Author: shiwn
     * @Param: [robotId]
     * @Return:
     */
    @Override
    public Map getRobotInfo(Integer robotId) {
        Map map = new HashMap();
        //  环境
        GhEnvDataVO envDataVO = getEnvData(robotId);
        map.put("envData", envDataVO);
        //  任务
        GhCurrentTaskVO currentTaskVO = getCurrentTask(robotId);
        map.put("taskData", currentTaskVO);
        //  自检
        Boolean robotCheck = getRobotCheck(getRobotIpById(robotId));
        map.put("checkData", robotCheck);
        //  地图
        RobotMapDTO mapDTO = getRobotMap(robotId);
        map.put("mapData", mapDTO);
        //  实时状态
        GhRobotStatusVO statusVO = getRobotStatus(getRobotIpById(robotId));
        map.put("robotData", statusVO);

        //  返回
        return map;
    }

    /**
     * @Description: 获取机器人的环境数据
     * @Date: 2022/7/5 9:36
     * @Author: shiwn
     * @Param: [robotId]
     * @Return:
     */
    private GhEnvDataVO getEnvData(Integer robotId) {
        GhEnvDataVO vo = new GhEnvDataVO();
        //  查询最新环境数据
        EnvDataDTO dto = envDataMapper.selectByRobotId(robotId);
        if (dto != null) {
            //  获取环境阈值
            Map<String, EnvSettingDTO> envSettingMap = envSettingService.getData();
            //  判断是否设置环境阈值
            boolean checkHumidity = false;
            boolean checkTemperature = false;
            boolean checkCo = false;
            boolean checkCo2 = false;
            boolean checkO3 = false;
            boolean checkSf6 = false;
            //  判断环境阈值是否告警
            if (!CollectionUtils.isEmpty(envSettingMap)) {
                List<AlarmResultVO> alarmList = envSettingService.envDataIsAlarm(dto, envSettingMap);

                AlarmResultVO humiditySet = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.HUMIDITY.getIndex())).findFirst().orElse(null);
                checkHumidity = humiditySet == null ? false : (Integer.parseInt(humiditySet.getAlarmLevel()) > 0 ? true : false);

                AlarmResultVO temperatureSet = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.TEMPERATURE.getIndex())).findFirst().orElse(null);
                checkTemperature = temperatureSet == null ? false : (Integer.parseInt(temperatureSet.getAlarmLevel()) > 0 ? true : false);

                AlarmResultVO coSet = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.CO.getIndex())).findFirst().orElse(null);
                checkCo = coSet == null ? false : (Integer.parseInt(coSet.getAlarmLevel()) > 0 ? true : false);

                AlarmResultVO co2Set = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.CO2.getIndex())).findFirst().orElse(null);
                checkCo2 = co2Set == null ? false : (Integer.parseInt(co2Set.getAlarmLevel()) > 0 ? true : false);

                AlarmResultVO o3Set = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.O3.getIndex())).findFirst().orElse(null);
                checkO3 = o3Set == null ? false : (Integer.parseInt(o3Set.getAlarmLevel()) > 0 ? true : false);

                AlarmResultVO sf6Set = alarmList.stream().filter(i -> i.getAlarmFor().equals(EnvTypeEnum.SF6.getIndex())).findFirst().orElse(null);
                checkSf6 = sf6Set == null ? false : (Integer.parseInt(sf6Set.getAlarmLevel()) > 0 ? true : false);
            }

            //  封装
            vo.setHumidity(dto.getHumidity());
            vo.setCheckHumidity(checkHumidity);

            vo.setTemperature(dto.getTemperature());
            vo.setCheckTemperature(checkTemperature);

            vo.setCo(dto.getCo());
            vo.setCheckCo(checkCo);

            vo.setCo2(dto.getCo2());
            vo.setCheckCo2(checkCo2);

            vo.setSf6(dto.getSf6());
            vo.setCheckSf6(checkSf6);

            vo.setO3(dto.getO3());
            vo.setCheckO3(checkO3);

            if (dto.getMq() != null) {
                vo.setMq(dto.getMq() > 0 ? "有" : "无");
            }
            if (dto.getFire() != null) {
                vo.setFire(dto.getFire() > 0 ? "有" : "无");
            }
            if (dto.getMq() != null) {
                vo.setAirQuality(dto.getMq() > 0 ? "有" : "无");
            }
        }
        //  返回
        return vo;
    }

    /**
     * @Description: 获取机器人实时状态数据
     * @Author: shiwn
     * @Param: [robotIp]
     * @Return:
     */
    private GhRobotStatusVO getRobotStatus(String robotIp) {
        GhRobotStatusVO vo = new GhRobotStatusVO();
        //  查询机器人是否离线
        RobotDTO robotDTO = robotMapper.selectRobotByIP(robotIp);
        if (robotDTO.getStatus() != 1) {
            return vo;
        }
        //  获取机器人实时状态信息
        RobotData robotData = (RobotData) redisUtils.get(RedisKey.ROBOT_DATA + robotIp);

        if (robotData != null) {
            //  封装
            vo.setSystemCom(robotData.getSystemCom());
            vo.setCap(robotData.getCap());
            vo.setTemp(robotData.getTemp());
            vo.setWorkTemp(robotData.getWorkTemp());
            vo.setChargingStatus(robotData.isChargingStatus());
            vo.setOpenRadar(robotData.isOpenRadar());
            vo.setMapX(robotData.getPosX());
            vo.setMapY(robotData.getPosY());

            //  判断告警
            vo = checkRobotWaring(vo, robotIp);
        }
        //  返回
        return vo;
    }

    /**
     * @Description: 获取实时任务数据
     * @Author: shiwn
     * @Return:
     */
    private GhCurrentTaskVO getCurrentTask(Integer robotId) {
        GhCurrentTaskVO vo = new GhCurrentTaskVO();
        if (robotId == null) {
            return vo;
        }
        //  获取正在执行的任务数据
        CheckTaskDTO taskDTO = taskMapper.selectByTaskStatus(robotId, TaskStatusEnum.WORKING.getCode());
        //  判断是否有正在执行的任务
        if (taskDTO == null) {
            //  没有则返回最新一条任务
            taskDTO = taskMapper.selectNewByRobotId(robotId);
            //  还没有则返回null
            if (taskDTO == null) {
                return vo;
            }
        }
        //  查询任务执行数据
        TaskDataDTO taskDataDTO = taskDataMapper.selectCurrentTask(taskDTO.getId());
        //  当前获取巡检点数据
        CheckPointDTO pointDTO = pointMapper.selectByPointId(taskDataDTO.getCurrentPoint());

        //  封装
        //  任务名称
        vo.setTaskName(taskDTO.getTaskName());
        //  任务状态
        vo.setTaskStatus(taskDTO.getTaskStatus());
        //  当前巡检点
        if (pointDTO != null) {
            vo.setPointName(pointDTO.getPointName());
        }
        //  预计时长
        vo.setUseTime(taskDataDTO.getUseTime());
        //  进度
        vo.setTaskProgress(taskDataDTO.getTaskProgress());
        //  全部点位数
        int total = taskDataDTO.getTotalPointNum();
        vo.setTotalPointNum(total);
        //  已巡检数
        int checked = taskDataDTO.getCheckedPointNum();
        vo.setCheckedPointNum(checked);
        //  未巡检数
        int notChecked = total - checked;
        vo.setNotCheckedPointNum(notChecked);
        //  异常数
        int error = taskDataDTO.getWarningPointNum();
        vo.setErrorPointNum(error);
        //  正常数
        int normal = checked - error;
        normal = normal < 0 ? 0 : normal;
        vo.setNormalPointNum(normal);

        //  返回
        return vo;
    }

    /**
     * @Description: 获取机器人自检告警状态
     * @Author: shiwn
     * @Param: [robotIp]
     * @Return:
     */
    private Boolean getRobotCheck(String robotIp) {
        return robotWarningService.getStatus(robotIp);
    }

    /**
     * @Description: 获取机器人地图数据
     * @Date: 2022/7/5 10:20
     * @Author: shiwn
     * @Param: [robotId]
     * @Return:
     */
    private RobotMapDTO getRobotMap(Integer robotId) {
        RobotMapDTO dto = mapService.getMapByRobotId(robotId);
        return dto;
    }

    /**
     * @Description: 查询任务列表
     * @Date: 2022/7/5 10:46
     * @Author: shiwn
     * @Param: [pageNum, pageSize, robotId]
     * @Return:
     */
    @Override
    public PageInfo getTaskList(Integer pageNum, Integer pageSize, Integer robotId) {
        //  初始化
        pageNum = pageNum == null ? 1 : pageNum;
        pageSize = pageSize == null ? 10 : pageSize;
        PageHelper.startPage(pageNum, pageSize);
        //  查询
        robotId = null;
        List list = taskMapper.selectTaskList(robotId);
        //  返回
        PageInfo pageOrg = new PageInfo<>(list);
        return pageOrg;
    }

    /**
     * @Description: 查询报告列表
     * @Date: 2022/7/5 10:52
     * @Author: shiwn
     * @Param: [pageNum, pageSize, robotId]
     * @Return:
     */
    @Override
    public PageInfo getReportList(Integer pageNum, Integer pageSize, Integer robotId) {
        //  初始化
        pageNum = pageNum == null ? 1 : pageNum;
        pageSize = pageSize == null ? 10 : pageSize;
        PageHelper.startPage(pageNum, pageSize);
        //  查询
        robotId = null;
        List list = reportMapper.selectReportList(robotId);
        //  返回
        PageInfo pageOrg = new PageInfo<>(list);
        return pageOrg;
    }

    /**
     * @Description: id 转 ip
     * @Date: 2022/7/5 11:44
     * @Author: shiwn
     * @Param: [robotId]
     * @Return:
     */
    private String getRobotIpById(Integer robotId) {
        String robotIp = "";
        if (listRobot.size() == 0) {
            getRobotList();
        }
        if (listRobot.size() > 0) {
            GhRobotVO dto = listRobot.stream().filter(i -> i.getRobotId().equals(robotId)).findFirst().get();
            robotIp = dto.getRobotIp();
        }
        return robotIp;
    }

    /**
     * @Description: ip 转 id
     * @Date: 2022/7/5 11:44
     * @Author: shiwn
     * @Param: [robotId]
     * @Return:
     */
    private Integer getRobotIdByIp(String robotIp) {
        Integer robotId = 0;
        if (listRobot.size() == 0) {
            getRobotList();
        }
        if (listRobot.size() > 0) {
            GhRobotVO dto = listRobot.stream().filter(i -> i.getRobotIp().equals(robotIp)).findFirst().get();
            robotId = dto.getRobotId();
        }
        return robotId;
    }

    /**
     * @Description: 机器人机身温度、电池温度、电量告警
     * @Author: shiwn
     */
    private GhRobotStatusVO checkRobotWaring(GhRobotStatusVO vo, String robotIp) {
        //  查询机器人id
        Integer robotId = getRobotIdByIp(robotIp);
        //  查询配置
        RobotSettingDTO dto = robotSettingMapper.selectByRobotId(robotId);
        //  判断告警
        if (dto != null) {
            //  机身温度
            Integer robotTemp = dto.getRobotTemp();
            if (robotTemp != null) {
                if (vo.getWorkTemp().compareTo((float) robotTemp) > 0) {
                    vo.setCheckWorkTemp(true);
                }
            }
            //  电池温度
            Integer batteryTemp = dto.getBatteryTemp();
            if (batteryTemp != null) {
                if (vo.getTemp().compareTo((float) batteryTemp) > 0) {
                    vo.setCheckTemp(true);
                }
            }
            //  电量
            Integer batteryLow = dto.getBatteryLow();
            if (batteryLow != null) {
                if (vo.getCap().compareTo((float) batteryLow) < 0) {
                    vo.setCheckCap(true);
                }
            }
        }
        return vo;
    }
}
