package com.zd.laboratory.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.enums.HardwareTypeEnum;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.laboratory.config.HardwareFunctionStatusConfig;
import com.zd.laboratory.domain.*;
import com.zd.laboratory.domain.LabRiskPlanAbnormalLog;
import com.zd.laboratory.domain.SubDiyAppVO;
import com.zd.laboratory.domain.SubDiyVO;
import com.zd.system.api.domain.SubQueryConfig;
import com.zd.laboratory.domain.vo.LabRiskPlanAbnormalLogVO;
import com.zd.laboratory.mapper.LabAbnormalMapper;
import com.zd.laboratory.mapper.LabPhotoNoteMapper;
import com.zd.laboratory.mapper.LabRiskPlanAbnormalLogMapper;
import com.zd.laboratory.service.ILabRiskPlanAbnormalLogService;
import com.zd.system.api.laboratory.domain.FunctionStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 风险异常日志Service业务层处理
 *
 * @author liubo
 * @date 2021-09-06
 */
@Service
public class LabRiskPlanAbnormalLogServiceImpl implements ILabRiskPlanAbnormalLogService {
    @Autowired
    private LabRiskPlanAbnormalLogMapper labRiskPlanAbnormalLogMapper;
    @Autowired
    private LabAbnormalMapper labAbnormalMapper;
    @Autowired
    private LabPhotoNoteMapper labPhotoNoteMapper;
    @Autowired
    SubQueryManager subQueryManager;
    @Autowired
    public HardwareFunctionStatusConfig hardwareFunctionStatusConfig;

    /**
     * 查询风险异常日志
     *
     * @param id 风险异常日志主键
     * @return 风险异常日志
     */
    @Override
    public LabRiskPlanAbnormalLog selectLabRiskPlanAbnormalLogById(Long id) {
        return labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogById(id);
    }


    /**
     * 根据预案id和组级id查询风险异常日志列表排序
     *
     * @param labRiskPlanAbnormalLog 风险异常日志
     * @return 风险异常日志集合
     */
    @Override
    public List<LabRiskPlanAbnormalLog> selectLabRiskPlanAbnormalLogOrderByList(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        return labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLog);
    }

    /**
     * 查询风险异常日志列表
     *
     * @param labRiskPlanAbnormalLog 风险异常日志
     * @return 风险异常日志
     */
    @Override
    @DataScope(deptAlias = "s", permi = PerPrefix.LABORATORY_PLANLOG)
    public List<LabRiskPlanAbnormalLog> selectLabRiskPlanAbnormalLogList(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        return labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogList(labRiskPlanAbnormalLog);
    }

    /**
     * 新增风险异常日志
     *
     * @param labRiskPlanAbnormalLog 风险异常日志
     * @return 结果
     */
    @Override
    public int insertLabRiskPlanAbnormalLog(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        labRiskPlanAbnormalLog.setCreateTime(DateUtils.getNowDate());
        return labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
    }

    /**
     * 修改风险异常日志
     *
     * @param labRiskPlanAbnormalLog 风险异常日志
     * @return 结果
     */
    @Override
    public int updateLabRiskPlanAbnormalLog(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        labRiskPlanAbnormalLog.setUpdateTime(DateUtils.getNowDate());
        return labRiskPlanAbnormalLogMapper.updateLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
    }

    /**
     * 批量删除风险异常日志
     *
     * @param ids 需要删除的风险异常日志主键
     * @return 结果
     */
    @Override
    public int deleteLabRiskPlanAbnormalLogByIds(Long[] ids) {
        return labRiskPlanAbnormalLogMapper.deleteLabRiskPlanAbnormalLogByIds(ids);
    }

    /**
     * 删除风险异常日志信息
     *
     * @param id 风险异常日志主键
     * @return 结果
     */
    @Override
    public int deleteLabRiskPlanAbnormalLogById(Long id) {
        return labRiskPlanAbnormalLogMapper.deleteLabRiskPlanAbnormalLogById(id);
    }

    /**
     * 风险发生数折线统计图
     */
    @Override
    @DataScope(deptAlias = "s", permi = PerPrefix.LABORATORY_PLANLOG)
    public List<Map<String, Object>> queryLineChart(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        return labRiskPlanAbnormalLogMapper.queryLineChart(labRiskPlanAbnormalLog);
    }

    /**
     * 风险发生占比图
     */
    @Override
    @DataScope(deptAlias = "s", permi = PerPrefix.LABORATORY_PLANLOG)
    public Map<String, List<Map<String, Object>>> queryHappenChart(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {

        Map<String, List<Map<String, Object>>> dataMap = new HashMap<>();
        labRiskPlanAbnormalLog.setChartType(1);
        dataMap.put("halfList", getMaps(labRiskPlanAbnormalLog));

        labRiskPlanAbnormalLog.setChartType(2);
        dataMap.put("nearlyList", getMaps(labRiskPlanAbnormalLog));

        labRiskPlanAbnormalLog.setChartType(3);
        dataMap.put("threeList", getMaps(labRiskPlanAbnormalLog));
        return dataMap;
    }

    private List<Map<String, Object>> getMaps(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {

        List<Map<String, Object>> maps = labRiskPlanAbnormalLogMapper.queryHappenChart(labRiskPlanAbnormalLog);
        Map<String, Object> newMap;
        List<Map<String, Object>> others;
        // 将数组下标 4到end 合并
        if (maps.size() > 4) {

            others = maps.subList(3, maps.size());
            newMap = new HashMap<>();
            newMap.put("riskPlanName", "其他");
            int count = 0;
            for (Map<String, Object> other : others) {
                count += (long) other.get("count");
            }
            newMap.put("count", count);

            maps = maps.subList(0, 3);
            maps.add(newMap);
        }
        return maps;
    }

    /**
     * 院系风险统计图
     */
    @Override
    @DataScope(deptAlias = "s", permi = PerPrefix.LABORATORY_PLANLOG)
    public Map<String, List<Map<String, Object>>> queryStatisticsChartDept(LabRiskPlanAbnormalLog labRiskPlanAbnormalLog) {
        Map<String, List<Map<String, Object>>> dataMap = new HashMap<>();
        List<Map<String, Object>> maps;
        labRiskPlanAbnormalLog.setChartType(1);
        maps = labRiskPlanAbnormalLogMapper.queryStatisticsChartDept(labRiskPlanAbnormalLog);
        dataMap.put("halfList", maps);

        labRiskPlanAbnormalLog.setChartType(2);
        maps = labRiskPlanAbnormalLogMapper.queryStatisticsChartDept(labRiskPlanAbnormalLog);
        dataMap.put("nearlyList", maps);

        labRiskPlanAbnormalLog.setChartType(3);
        maps = labRiskPlanAbnormalLogMapper.queryStatisticsChartDept(labRiskPlanAbnormalLog);
        dataMap.put("threeList", maps);
        return dataMap;
    }

    /**
     * 近30天预案执行数
     */
    @Override
    public int queryPlanCount() {
        return labRiskPlanAbnormalLogMapper.queryPlanCount();
    }

    /**
     * 风险趋势统计图
     */
    @Override
    public Map<String, Map<String, List<Map<String, Object>>>> queryRiskTrend(Map<String, Object> params) {
        Map<String, Map<String, List<Map<String, Object>>>> result = new HashMap<>();

        Map<String, List<Map<String, Object>>> dataMap = new HashMap<>();
        List<Map<String, Object>> maps;

        // 风险数
        params.put("type", 1);
        maps = labRiskPlanAbnormalLogMapper.queryRiskTrend(params);
        dataMap.put("risks", maps);

        // 故障数
        maps = labAbnormalMapper.queryFailures(params);
        dataMap.put("failures", maps);

        // 隐患数
        maps = labPhotoNoteMapper.selectDangers(params);
        dataMap.put("dangers", maps);

        // 近7天数据
        result.put("sevenDays", dataMap);

        /** ----------------------- 30天数据，暂时不要--------------------------- */
        /*dataMap = new HashMap<>();

        // 风险数
        params.put("type", 2);
        maps = labRiskPlanAbnormalLogMapper.queryRiskTrend(params);
        dataMap.put("risks", maps);

        // 故障数
        maps = labAbnormalMapper.queryFailures(params);
        dataMap.put("failures", maps);

        // 隐患数
        maps = labPhotoNoteMapper.selectDangers(params);
        dataMap.put("dangers", maps);

        // 近30天数据
        result.put("oneMonth", dataMap);*/
        return result;
    }

    /**
     * 小程序查询当前发生的实验室风险异常日志列表
     *
     * @param labRiskPlanAbnormalLogVo 风险异常日志
     * @return 风险异常日志
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", subAdmin = true)
    public List<SubDiyAppVO> selectLabRiskPlanAppList(LabRiskPlanAbnormalLogVO labRiskPlanAbnormalLogVo) {
        if(labRiskPlanAbnormalLogVo.getCount()==0){
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            labRiskPlanAbnormalLogVo.setShowTime(sdf.format(d));
        }else if(labRiskPlanAbnormalLogVo.getCount()==1){
            SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
            Date beginDate = new Date();
            Calendar date = Calendar.getInstance();
            date.setTime(beginDate);
            date.set(Calendar.DATE, date.get(Calendar.DATE) - 1);
            labRiskPlanAbnormalLogVo.setShowTime(dft.format(date.getTime()));
        }
        List<LabRiskPlanAbnormalLogVO> riskPlanLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAppList(labRiskPlanAbnormalLogVo);
        Long todayHappenCount = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAppHappenCount(labRiskPlanAbnormalLogVo);
        LinkedMultiValueMap<Long,LabRiskPlanAbnormalLogVO> riskPlanMap = new LinkedMultiValueMap();
        Optional.ofNullable(riskPlanLogList).filter(a->a.size()>0).orElseGet(Collections::emptyList)
                .forEach(a->{
                    riskPlanMap.add(a.getGroupId(),a);
                });

        List<SubDiyAppVO> subSensorList = new ArrayList();
        Optional.ofNullable(riskPlanMap).filter(a->a.size()>0).ifPresent(a->{
                    a.entrySet().forEach(b->{
                        Set<String> describeSet = new HashSet();
                        Set<Long> subjectSet = new HashSet();

                        SubDiyAppVO appVo = new SubDiyAppVO();
                        Optional.ofNullable(b.getValue()).filter(v2->v2.size()>0).orElseGet(Collections::emptyList).stream().forEach(t->{
                            subjectSet.add(t.getSubjectId());
                            //解析日志的json数据，用作页面展示提示传感器信息
                            JSONArray sensorList = JSONObject.parseArray(t.getSensorJson());
                            for(int x=0;x<sensorList.size();x++){
                                JSONObject jsonObj=sensorList.getJSONObject(x);
                                describeSet.add(jsonObj.get("describe")+"检测数值异常");
                            }
                            appVo.setGroupStatus(t.getGroupStatus());
                            appVo.setBeginDate(t.getCreateTime());
                            appVo.setRiskPlanLogId(t.getId());
                        });
                        Long subjectId = subjectSet.iterator().next();
                        SubQueryConfig subQueryConfig = new SubQueryConfig();
                        subQueryConfig.setDangerLevel(true);
                        subQueryConfig.setAddr(true);
                        subQueryConfig.setConversionDictSubName(true);
                        List<SubDiyVO> subDiy = subQueryManager.querySubs(subQueryConfig,subjectId);

                        appVo.setSensorSet(describeSet);
                        if(subDiy.size()>0){
                            appVo.setSubDiyVo(subDiy.get(0));
                        }
//                        appVo.setSubDiyVo(Optional.ofNullable(subDiy).filter(p->p.size()>0).orElseGet(Collections::emptyList).get(0));
                        appVo.setTodayHappenCount(todayHappenCount);

                        //加入实验室信息
                        if(riskPlanLogList.size()>0){
                            LabSubject subject = new LabSubject();
                            subject.setId(subjectId);
                            List<SubDiyVO> subDiyVOList = subQueryManager.querySubs(subject, SubQueryConfig.subQueryConfigList);
                            if(subDiyVOList.size()>0){
                                appVo.setSubDiyNewVO(subDiyVOList.get(0));
                            }
                        }
                        subSensorList.add(appVo);

                    });
                }
        );
        return subSensorList;
    }


    /**
     * 小程序查询当前发生的实验室风险异常日志统计
     *
     * @param labRiskPlanAbnormalLogVo 风险异常日志
     * @return 风险异常日志
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", subAdmin = true)
    public Map<String,Integer> selectLabRiskPlanAppCount(LabRiskPlanAbnormalLogVO labRiskPlanAbnormalLogVo) {
        Map<String,Integer> riskPlanLogCount = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAppCount(labRiskPlanAbnormalLogVo);
        return riskPlanLogCount;
    }


    /**
     * 小程序查询登录人管理实验室下的预案记录列表
     *
     * @param labRiskPlanAbnormalLogVo 风险异常日志
     * @return 风险异常日志
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", subAdmin = true)
    public List<SubDiyAppVO> adminSubByRiskPlan(LabRiskPlanAbnormalLogVO labRiskPlanAbnormalLogVo) {
        labRiskPlanAbnormalLogVo.setAdminId(SecurityUtils.getUserId());
        labRiskPlanAbnormalLogVo.setRiskStatus(1L);
        List<LabRiskPlanAbnormalLogVO> riskPlanLogList = labRiskPlanAbnormalLogMapper.adminSubByRiskPlan(labRiskPlanAbnormalLogVo);
        List<SubDiyAppVO> subRiskPlanList = new ArrayList();
        Optional.ofNullable(riskPlanLogList).filter(a->a.size()>0).ifPresent(a->{
            a.forEach(b->{
                SubDiyAppVO appVo = new SubDiyAppVO();
                Long subjectId = b.getSubjectId();
                SubQueryConfig subQueryConfig = new SubQueryConfig();
                subQueryConfig.setAddr(true);
                subQueryConfig.setConversionDictSubName(true);
                List<SubDiyVO> subDiy = subQueryManager.querySubs(subQueryConfig,subjectId);
                appVo.setSubDiyVo(Optional.ofNullable(subDiy).filter(p->p.size()>0).orElseGet(Collections::emptyList).get(0));
                appVo.setRiskPlanAbnormalLogVo(b);
                //这里查询风险预案下的硬件电源记录
                LabRiskPlanAbnormalLogVO labRiskPlanAbnormalLogVoByhard = new LabRiskPlanAbnormalLogVO();
                labRiskPlanAbnormalLogVoByhard.setGroupId(b.getGroupId());
                labRiskPlanAbnormalLogVoByhard.setRiskPlanId(b.getRiskPlanId());
                labRiskPlanAbnormalLogVoByhard.setRiskStatus(0L);
                List<LabRiskPlanAbnormalLogVO> riskPlanLogListBySwitch = labRiskPlanAbnormalLogMapper.adminSubByRiskPlan(labRiskPlanAbnormalLogVoByhard);
                if(riskPlanLogListBySwitch.size()>0){
                    HardwareOpreteActVO opreteVo = new HardwareOpreteActVO();
                    opreteVo.setHardWareName(HardwareTypeEnum.SWITCH.getName());
                    opreteVo.setHardWareOpreteAct(riskPlanLogListBySwitch.get(0).getRiskPlanName());
                    opreteVo.setOpreteFlag(true);
                    opreteVo.setOpreteMes("执行成功");
                    appVo.getHardwareOpreteActList().add(opreteVo);
                }
                //这里查询风险预案下的硬件风扇记录
                labRiskPlanAbnormalLogVoByhard.setGroupId(b.getGroupId());
                labRiskPlanAbnormalLogVoByhard.setRiskPlanId(b.getRiskPlanId());
                labRiskPlanAbnormalLogVoByhard.setRiskStatus(3L);
                List<LabRiskPlanAbnormalLogVO> riskPlanLogListByAi = labRiskPlanAbnormalLogMapper.adminSubByRiskPlan(labRiskPlanAbnormalLogVoByhard);
                if(riskPlanLogListByAi.size()>0){
                    HardwareOpreteActVO opreteVo = new HardwareOpreteActVO();
                    opreteVo.setHardWareName(HardwareTypeEnum.AI_VENTILATION.getName());
                    opreteVo.setHardWareOpreteAct(riskPlanLogListByAi.get(0).getRiskPlanName());
                    opreteVo.setOpreteFlag(true);
                    opreteVo.setOpreteMes("执行成功");
                    appVo.getHardwareOpreteActList().add(opreteVo);
                }
                //这里是查询语音播报日志，是否插入。
                labRiskPlanAbnormalLogVoByhard.setGroupId(b.getGroupId());
                labRiskPlanAbnormalLogVoByhard.setRiskPlanId(b.getRiskPlanId());
                labRiskPlanAbnormalLogVoByhard.setRiskStatus(5L);
                List<LabRiskPlanAbnormalLogVO> riskPlanLogListByVoice = labRiskPlanAbnormalLogMapper.adminSubByRiskPlan(labRiskPlanAbnormalLogVoByhard);
                if(riskPlanLogListByVoice.size()>0){
                    HardwareOpreteActVO opreteVo = new HardwareOpreteActVO();
                    opreteVo.setHardWareName("语音播报");
                    opreteVo.setHardWareOpreteAct(riskPlanLogListByVoice.get(0).getVoicebroadcast());
                    opreteVo.setOpreteFlag(true);
                    opreteVo.setOpreteMes("执行成功");
                    appVo.getVoiceOpreteActList().add(opreteVo);
                }

                //这里是查询语音电话短信，是否执行成功。
                if(subDiy.size()>0){
                    SubDiyVO diyVo = subDiy.get(0);
                    Map<String, Object> params = new HashMap <>();
                    params.put("phone",diyVo.getAdminPhone());
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateString = formatter.format(b.getCreateTime());
                    params.put("strCreateTime",dateString);
                    List<AlarmLog> alarmLogList = labRiskPlanAbnormalLogMapper.selectNoBackAlarmLogList(params);
                    if(alarmLogList.size()>0){
                        AlarmLog alarmLog = alarmLogList.get(0);
                        HardwareOpreteActVO phoneOpreteVo = new HardwareOpreteActVO();
                        phoneOpreteVo.setHardWareName("语音电话");
                        phoneOpreteVo.setHardWareOpreteAct(alarmLog.getNotice());
                        phoneOpreteVo.setOpreteFlag(true);
                        if(alarmLog.getIsBack()>0){
                            phoneOpreteVo.setOpreteMes("执行成功");
                        }else{
                            phoneOpreteVo.setOpreteMes("执行中");
                        }
                        appVo.getPhoneOpreteActList().add(phoneOpreteVo);

                        HardwareOpreteActVO messageOpreteVo = new HardwareOpreteActVO();
                        messageOpreteVo.setHardWareName("短信提醒");
                        messageOpreteVo.setHardWareOpreteAct(alarmLog.getNotice());
                        messageOpreteVo.setOpreteFlag(true);
                        if(alarmLog.getIsBack()>0){
                            messageOpreteVo.setOpreteMes("执行成功");
                        }else{
                            messageOpreteVo.setOpreteMes("执行中");
                        }
                        appVo.getMessageOpreteActList().add(messageOpreteVo);
                    }else{
                        HardwareOpreteActVO phoneOpreteVo = new HardwareOpreteActVO();
                        phoneOpreteVo.setHardWareName("语音电话");
                        phoneOpreteVo.setOpreteFlag(false);
                        phoneOpreteVo.setOpreteMes("执行失败");
                        appVo.getPhoneOpreteActList().add(phoneOpreteVo);

                        HardwareOpreteActVO messageOpreteVo = new HardwareOpreteActVO();
                        messageOpreteVo.setHardWareName("短信提醒");
                        messageOpreteVo.setOpreteFlag(false);
                        messageOpreteVo.setOpreteMes("执行失败");
                        appVo.getMessageOpreteActList().add(messageOpreteVo);
                    }
                }


                subRiskPlanList.add(appVo);

            });
        });

        return subRiskPlanList;
    }

}
