package com.pqs9900.serviceImpl.terminal;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.log.LogFactory;
import com.njcn.enums.TerminalLogsEnum;
import com.njcn.mapper.configuration.*;
import com.njcn.pojo.commons.device.DeviceDetail;
import com.njcn.pojo.configuration.Device;
import com.njcn.pojo.configuration.NodeInformation;
import com.njcn.pojo.configuration.PushInfo;
import com.njcn.pojo.configuration.TerminalLogs;
import com.njcn.serviceimpl.configuration.DeviceServiceImpl;
import com.njcn.shiro.token.TokenManager;
import com.njcn.sso.pojo.user.User;
import com.njcn.utils.AppConfig;
import com.njcn.utils.PubUtils;
import com.njcn.utils.SocketClient;
import com.pqs9900.mapper.DataInfo.FlowDetailMapper;
import com.pqs9900.mapper.DataInfo.FlowMapper;
import com.pqs9900.mapper.DataInfo.VersionMapper;
import com.pqs9900.mapper.terminal.FlowMealMapper;
import com.pqs9900.mapper.terminal.TerminalStateMapper;
import com.pqs9900.pojo.terminal.*;
import com.pqs9900.service.terminal.TerminalStateService;
import jdk.nashorn.internal.ir.Terminal;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 终端运行管理
 * @Author cdf
 * @Date 2020/8/28 15:12
 **/
@Service
public class TerminalStateServiceImpl implements TerminalStateService {
    private final static Logger logger = LoggerFactory.getLogger(TerminalStateServiceImpl.class);

    @Autowired
    private TerminalStateMapper terminalStateMapper;

    @Autowired
    private PushInfoMapper pushInfoMapper;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private NodeInformationMapper nodeInformationMapper;
    @Autowired
    private VersionMapper versionMapper;
    @Resource
    private TerminalLogsMapper terminalLogsMapper;
    @Autowired
    private SocketClient socketClient;
    @Autowired
    private AppConfig appConfig;
    @Autowired
    private FlowMealMapper flowMealMapper;

    @Autowired
    private LineMapper lineMapper;

    /**
     * @Author chendaofei
     * @Description
     * @Date 10:40 2020/8/31
     **/
    @Override
    public List<TerminalRVO> getTerminalList(String devType, Integer status,String startTime) {
        return terminalStateMapper.getTerminalList(devType, status,startTime);
    }

    /**
     * @Author chendaofei
     * @Description
     * @Date 10:40 2020/8/31
     **/
    @Override
    public List<TerminalRVO> getTerminalList2(List<String> list) {
        return terminalStateMapper.getTerminalList2(list);
    }

    /**
     * @Author chendaofei
     * @Description 批量修改终端运行状态
     * @Date 9:23 2020/9/2
     **/
    @Override
    public Integer updateDevFlag(TerminalParamVO terminalParamVO) {
        try {
            List<Integer> devList = terminalParamVO.getList().stream().map(item -> {
                return Integer.valueOf(item);
            }).collect(Collectors.toList());
            List<Device> devResList = deviceMapper.getDevicesByDevIndexs(devList);
            if (CollectionUtil.isNotEmpty(devResList)) {
                List<TerminalLogs> logsList = new ArrayList<>();
                for (Device devIndex : devResList) {
                    String devFlag = devFlag(devIndex.getDevFlag());
                    String terminalDescribeReason = "由" + devFlag + "状态更改到" + devFlag(terminalParamVO.getDevFlag()) + "状态，原因是" + terminalParamVO.getDescribe();
                    TerminalLogs terminalLogs = new TerminalLogs();
                    terminalLogs.setLogsIndex(UUID.randomUUID().toString());
                    terminalLogs.setObjIndex(devIndex.getDevIndex().toString());
                    terminalLogs.setTerminalType(TerminalLogsEnum.deviceLogs.getTerminalIndex());
                    String deviceDescribe = deviceMapper.deviceDescribe(devIndex.getDevIndex().intValue());
                    terminalLogs.setTerminalDescribe(TokenManager.getNickname() + deviceDescribe + terminalDescribeReason);
                    terminalLogs.setUpdateTime(new Date());
                    terminalLogs.setUserIndex(TokenManager.getUserId());
                    logsList.add(terminalLogs);
                    /**
                     * 修改装置状态后，将装置下的监测点全部设置为相同状态
                     */
                    lineMapper.updateLineStatus(terminalParamVO.getDevFlag(),devIndex.getDevIndex());
                }
                terminalLogsMapper.batchAddTerminalLogs(logsList);
            }
            Integer res = terminalStateMapper.updateDevFlag(terminalParamVO.getList(), terminalParamVO.getDevFlag());

            topushInfo(terminalParamVO.getList());
            return res;
        }catch (Exception e){
            logger.error("更改终端状态出错,错误信息"+e.getMessage());
            return -1;
        }
    }

    String devFlag(Integer devFlag){
        switch (devFlag){
            case 0 : return "投运";
            case 1 : return "检修";
            case 2 : return "退运";
            default:return "";
        }
    }

    /**
     * @Author chendaofei
     * @Description 配置终端流量套餐
     * @Date 12:26 2020/9/21
     **/
    @Override
    @Transactional
    public Integer addDevMealAss(List<String> list, String fmBaseIndex, String fmReamIndex) {
        List<TerminalMealAssDTO> objList = new ArrayList();
        terminalStateMapper.delDevMealAss(list);
        for (String devIndex : list) {
            TerminalMealAssDTO terminalMealAssDTO = new TerminalMealAssDTO();
            terminalMealAssDTO.setDevIndex(devIndex);
            terminalMealAssDTO.setFmBaseIndex(fmBaseIndex);
            terminalMealAssDTO.setFmReamIndex(fmReamIndex);
            terminalMealAssDTO.setUpdateTime(new Date());
            terminalMealAssDTO.setUpdateUser(TokenManager.getUserId());
            objList.add(terminalMealAssDTO);
        }
        int res = terminalStateMapper.addDevMealAss(objList);
        if (res == list.size()) {
            //成功
            topushInfo(list);

            Integer expend = 0;
            FlowMealDTO flowMealDTO = flowMealMapper.selectByPrimaryKey(fmBaseIndex);

            FlowMealDTO flowMealDTOexpend;

            if(StrUtil.isNotBlank(fmReamIndex)) {
                flowMealDTOexpend = flowMealMapper.selectByPrimaryKey(fmReamIndex);
                if(Objects.nonNull(flowMealDTOexpend)){
                    expend = flowMealDTOexpend.getFmNumber();
                }
            }
            //记录日志
            List<TerminalLogs> logsList = new ArrayList<>();
            for (String devIndex : list) {
                DeviceDetail deviceDetail = deviceMapper.getDevAndParent(devIndex);
                if(Objects.nonNull(deviceDetail)) {
                    TerminalLogs terminalLogs = new TerminalLogs();
                    terminalLogs.setLogsIndex(UUID.randomUUID().toString());
                    terminalLogs.setObjIndex(devIndex);
                    terminalLogs.setTerminalType(TerminalLogsEnum.flowLogs.getTerminalIndex());
                    String deviceDescribe = TokenManager.getNickname() +
                            "将 " + deviceDetail.getGdNa()+" 下的 "+deviceDetail.getSubName()+" 下的 "
                            +deviceDetail.getName()+" 基础流量套餐设置为: "+flowMealDTO.getFmNumber()+"; 扩展流量套餐设置为"+expend;
                    terminalLogs.setTerminalDescribe(deviceDescribe);
                    terminalLogs.setUpdateTime(new Date());
                    terminalLogs.setUserIndex(TokenManager.getUserId());
                    logsList.add(terminalLogs);
                }
            }
            terminalLogsMapper.batchAddTerminalLogs(logsList);
        }
        return res;
    }

    /**
     * @Author chendaofei
     * @Description 新增设备流量策略关系表
     * @Date 12:26 2020/9/21
     **/
    @Override
    public Integer addDevStrategyAss(List<String> list, String fsIndex) {
        List<TerminalStrategyAssDTO> objList = new ArrayList();
        terminalStateMapper.delStrategyAss(list);
        for (String devIndex : list) {
            TerminalStrategyAssDTO terminalStrategyAssDTO = new TerminalStrategyAssDTO();
            terminalStrategyAssDTO.setDevIndex(devIndex);
            terminalStrategyAssDTO.setFsIndex(fsIndex);
            terminalStrategyAssDTO.setUpdateTime(new Date());
            terminalStrategyAssDTO.setUpdateUser(TokenManager.getUserId());
            objList.add(terminalStrategyAssDTO);
        }
        int res = terminalStateMapper.addStrategyAss(objList);
        if (res == list.size()) {
            //成功

            topushInfo(list);

        }
        return res;
    }

    /**
     * @Author chendaofei
     * @Description 发起重启服务器
     * @Date 10:47 2020/9/22
     **/
    @Override
    public String getWebIpList(){
        List<String> list = terminalStateMapper.getPushInfoList();
        if(!CollectionUtil.isEmpty(list)) {
            User user = TokenManager.getToken();
            String name = user.getLoginName();
            Integer port = Integer.valueOf(appConfig.getSocketPort());
            JSONObject jsonObject = new JSONObject();
            Map<String,String> map = new HashMap();
            map.put("type","200");

            for(int i=0;i<list.size();i++){
                String ip = list.get(i);
                map.put("ip",ip);
                jsonObject.put("data",map);
                Integer len = jsonObject.get("data").toString().length();
                jsonObject.put("len",len.toString());
                socketClient.sentCloseWeb(jsonObject.toString(),name,ip,port);
            }
            return "执行成功";
        }
        return "没有需要重启的前置";
    }

    /**
     * @Author chendaofei
     * @Description 获取当前终端的流量详情
     * @Date 10:47 2020/9/22
     **/
    @Override
    public FlowDetailRVO getTerminalFlowDetail(String devIndex,String startTime){
        FlowDetailRVO flowDetailRVO = terminalStateMapper.getTerminalFlowDetail(devIndex,startTime);
        return flowDetailRVO;
    }

    /**
     * @Author chendaofei
     * @Description 流量统计柱状图数据获取
     * @Date 20:39 2020/10/9
     **/
    @Override
    public List<FlowStatisticsRVO> getFlowStatiscsList(String startTime, List<String> list, String mealBi, String mealUse, String mealAll){
        return terminalStateMapper.getFlowStatiscsList(startTime,list,mealBi,mealUse,mealAll);
    }

    /**
     * @Author chendaofei
     * @Description 统计日流量流量图表数据
     * @Date 21:34 2020/10/12
     **/
    @Override
    public List<FlowStatisticsRVO> getDayFlowList(String devIndex,String startTime){
        return terminalStateMapper.getDayFlowList(devIndex,startTime);
    }


    /**
     * @Author chendaofei
     * @Description 获取终端性能
     * @Date 9:46 2020/10/14
     **/
    @Override
    public String getQuailty(String devIndex){
        String ip = terminalStateMapper.getIpByTerminal(devIndex);
        if(PubUtils.isBlank(ip)){
            return "获取失败";
        }
        JSONObject jsonObject = new JSONObject();
        Map<String,String> map = new HashMap<>();
        map.put("type","190");
        map.put("index",devIndex);
        map.put("hander","1");
        jsonObject.put("data",map);
        Integer len = jsonObject.get("data").toString().length();
        jsonObject.put("len",len.toString());

        Integer port = Integer.valueOf(appConfig.getSocketPort());
        User user = TokenManager.getToken();
        String name = user.getLoginName();
        socketClient.showQuaity(jsonObject.toString(),ip,port,name);
        return "获取成功";
    }

    /**
     * @Author chendaofei
     * @Description 关闭Socket
     * @Date 15:13 2020/10/14
     **/
    @Override
    public String closeSocket(String devIndex){
        String ip = terminalStateMapper.getIpByTerminal(devIndex);
        try {
            JSONObject jsonObject = new JSONObject();
            Map<String, String> map = new HashMap<>();
            map.put("type", "190");
            map.put("index", devIndex);
            map.put("hander", "0");
            jsonObject.put("data", map);
            Integer len = jsonObject.get("data").toString().length();
            jsonObject.put("len", len.toString());
            socketClient.closeMySocket(jsonObject.toString(),ip,Integer.valueOf(appConfig.getSocketPort()));
            return "执行成功";
        }catch (Exception e){
            return "执行失败";
        }


    }

    /**
     * @Author chendaofei
     * @Description 心跳机制Socket
     * @Date 15:13 2020/10/14
     **/
    @Override
    public String heartSocket(String devIndex){
        JSONObject jsonObject = new JSONObject();
        Map<String, String> map = new HashMap();
        map.put("type", "190");
        map.put("hander", "2");
        map.put("index", devIndex);
        jsonObject.put("data", map);
        Integer len = jsonObject.get("data").toString().length();
        jsonObject.put("len", len.toString());
        String ip = terminalStateMapper.getIpByTerminal(devIndex);
        return socketClient.heartSocket(jsonObject.toString(),ip,Integer.valueOf(appConfig.getSocketPort()));
    }

    private void topushInfo(List<String> list){

        for (String devIndex : list) {
            Device tmp = deviceMapper.selectByPrimaryKey(Long.valueOf(devIndex));
            if (tmp != null) {
                NodeInformation tmpNode = nodeInformationMapper.selectByPrimaryKey(tmp.getNodeIndex());
                if (tmpNode != null) {
                    PushInfo pushInfo = new PushInfo();
                    pushInfo.setPiIndex(UUID.randomUUID().toString());
                    pushInfo.setNodeName(tmpNode.getNodeName());
                    pushInfo.setNodeIP(tmpNode.getNodeIP());
                    pushInfo.setPushType(0L);
                    pushInfo.setActType(0L);
                    pushInfo.setMyIndex(Long.valueOf(devIndex));
                    pushInfo.setMyName(tmp.getName());
                    pushInfo.setState(1L);
                    pushInfo.setUpdateTime(new Date());
                    pushInfoMapper.insert(pushInfo);

                }
            }
        }
    }

}
