package com.pqs9000.controller.area;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.njcn.enums.LogTypeEnum;
import com.njcn.mapper.configuration.DicDataMapper;
import com.njcn.mapper.configuration.TerminalLogsMapper;
import com.njcn.pojo.commons.DatePojo;
import com.njcn.pojo.commons.HttpResult;
import com.njcn.pojo.commons.device.DeviceGeneral;
import com.njcn.pojo.commons.device.LineDetailInfo;
import com.njcn.pojo.commons.runmanage.IntegrityAnalysisData;
import com.njcn.pojo.commons.runmanage.IntergralityData;
import com.njcn.pojo.configuration.*;
import com.njcn.service.configuration.DeviceService;
import com.njcn.service.log.UserLogDetailService;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.AppConfig;
import com.njcn.utils.PubUtils;
import com.pqs9000.pojo.report.IntegrityDetailVo;
import com.pqs9000.service.report.GetInegDataService;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author hongawen
 * @Date: 2018/6/22 14:13
 */
@Controller
@RequestMapping("area")
public class IntegralityController {

    private static final Logger logger = LoggerFactory.getLogger(IntegralityController.class);

    @Autowired
    private DeviceService deviceService;

    @Autowired
    UserLogDetailService userLog;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private DicDataMapper dicDataMapper;

    @Autowired
    private TerminalLogsMapper terminalLogsMapper;

    @Autowired
    private GetInegDataService getInegDataService;

    /**
     * 跳转区域统计的数据完整性
     */
    @GetMapping("integrality")
    public String status() {
        return "business/area/dataIntegrality";
    }


    /**
     * 跳转运行管理的监测点数据完整性
     * type 统计类型（冀北省、国网）
     */
    @GetMapping("integralitytable")
    public ModelAndView integrityTable(String starttime, String endtime, String area, String interval, String gwtype) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("business/manage/integrityTable");
        if(StringUtils.isEmpty(starttime)&&StringUtils.isEmpty(endtime)){
            modelAndView.addObject("startTime", "");
            modelAndView.addObject("endTime", "");
        }else{
            DatePojo datePojo=PubUtils.validateDate(starttime,endtime,"integralitytable");
            if(!StringUtils.isEmpty(datePojo.getMsg())){
                modelAndView.addObject("startTime", "");
                modelAndView.addObject("endTime", "");
            }else{
                modelAndView.addObject("startTime", starttime);
                modelAndView.addObject("endTime", endtime);
            }
        }
        modelAndView.addObject("area", area);
        modelAndView.addObject("interval", interval);
        modelAndView.addObject("gwType", gwtype);
        return modelAndView;
    }


    /**
     * 运行管理--》监测点数据完整性
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     * @param area      区域
     */
    @PostMapping("getIntegrityData")
    @ResponseBody
    public HttpResult getIntegrityData(String startTime, String endTime, String area,Integer devflag,Integer powerId, Integer runFlag, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getIntegrityData");
        if (!StringUtils.isEmpty(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        IntergralityData intergralityData;
        try {
            intergralityData = deviceService.getDataIntegralityTable(datePojo.getStartTime(), datePojo.getEndTime(), area,devflag,powerId,runFlag);
            if (null == intergralityData) {
                result = PubUtils.assignmentResultLog(null, 500, "获取监测点数据完整性数据为空", "查询完整性列表", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(intergralityData, 200, "获取监测点数据完整性数据成功", "查询完整性列表", "成功", result);
            }
            userLog.getLog("查询监测点数据完整性", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } catch (Exception e) {
            logger.error("获取终端运行数据异常,异常为：" + e.toString());
            result = PubUtils.assignmentResultLog(null, 500, "获取监测点数据完整性数据异常", "查询完整性列表", "成功", result);
            userLog.getLog("查询监测点数据完整性", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        }
        return result;
    }


    /**
     * 区域统计--》数据完整性
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    @PostMapping("dataIntegrality")
    @ResponseBody
    public HttpResult dataIntegrality(String startTime, String endTime, String overview, String area,
                                      String scale, String manc, String loadtype, Integer monitorNature, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "dataIntegrality");
        if (!StringUtils.isEmpty(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        DeviceGeneral data;
        try {
            data = deviceService.getDataIntegrality(datePojo.getStartTime(), datePojo.getEndTime(), overview, area, scale, manc, loadtype, monitorNature);
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "获取数据完整性数据为空", "查询数据完整性", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(data, 200, "获取数据完整性数据成功", "查询数据完整性", "成功", result);
            }
            userLog.getLog("查询数据完整性数据", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } catch (Exception e) {
            logger.error("获取终端运行数据异常,异常为：" + e.toString());
            userLog.getLog("查询数据完整性数据", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResultLog(null, 500, "获取数据完整性数据异常", "查询数据完整性", "失败", result);
        }
        return result;
    }


    /**
     * 监测点数据补招
     * @date 2023/7/27
     */
    @GetMapping("integralityRepair")
    @ResponseBody
    public HttpResult integralityRepair(String startTime, String endTime, Long lineId,Long devId) {

        HttpResult result;
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "integralityRepair");
        if (StrUtil.isNotBlank(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }

        String nodeIp = "";
        Device deviceInfo = deviceService.selectDeviceByIndex(devId);
        if(Objects.nonNull(deviceInfo)){
            NodeInformation nodeInfo =  deviceService.setIp(deviceInfo.getNodeIndex().intValue());
            nodeIp = nodeInfo.getNodeIP();
        }

        Socket socket = null;
        BufferedReader in = null;
        OutputStream out = null;
        try{
            socket = new Socket(nodeIp, Integer.parseInt(appConfig.getSocketPort()));
            socket.setSoTimeout(3000);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
            out = socket.getOutputStream();

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("startTime",startTime);
            jsonObject.put("endTime",endTime);
            jsonObject.put("lineId",lineId);
            jsonObject.put("index",devId);
            jsonObject.put("type","240");

            JSONObject jsonObjectOne = new JSONObject();
            jsonObjectOne.put("len",jsonObject.toString().length());
            jsonObjectOne.put("data",jsonObject);


            //System.out.println(jsonObjectOne.toString());

            out.write(jsonObjectOne.toString().getBytes(StandardCharsets.UTF_8));
            //socket.shutdownOutput();
            String expression;

            while ((expression = in.readLine())==null){break;} {
                try {
                    logger.info("accept msg:"+expression);
                    JSONObject res = JSONObject.fromObject(expression);
                    TerminalLogs terminalLogs = new TerminalLogs();

                    SubStation subStation = deviceService.loadSub(deviceInfo.getSubIndex());
                    LineDetailInfo lineDetail = deviceService.loadLine(lineId);
                    DicData dicData = dicDataMapper.getSelName("监测点数据完整性补招");

                    terminalLogs.setLogsIndex(IdUtil.randomUUID());
                    terminalLogs.setTerminalType(dicData.getDicIndex());
                    terminalLogs.setUserIndex(TokenManager.getUserId());
                    terminalLogs.setUpdateTime(new Date());
                    terminalLogs.setObjIndex(lineId.toString());
                    if("10000".equalsIgnoreCase(res.get("resultcode").toString())){
                        //成功
                        terminalLogs.setTerminalDescribe(TokenManager.getNickname()+"进行对"+subStation.getName()+"_"+lineDetail.getName()+"的数据补招，补招时间段:"+startTime+"到"+endTime+";补招结果"+"成功：");
                        terminalLogsMapper.insert(terminalLogs);
                        return PubUtils.assignmentResult(null, 200, "数据完整性补招成功");
                    }else if("10010".equalsIgnoreCase(res.get("resultcode").toString())) {
                        //错误
                        terminalLogs.setTerminalDescribe(TokenManager.getNickname()+"进行对"+subStation.getName()+"_"+lineDetail.getName()+"的数据补招，补招时间段:"+startTime+"到"+endTime+";补招结果"+"失败；");
                        terminalLogsMapper.insert(terminalLogs);
                        return PubUtils.assignmentResult(null, 500, "当前监测点无此功能");
                    }else {
                        //错误
                        terminalLogs.setTerminalDescribe(TokenManager.getNickname()+"进行对"+subStation.getName()+"_"+lineDetail.getName()+"的数据补招，补招时间段:"+startTime+"到"+endTime+";补招结果"+"失败；");
                        terminalLogsMapper.insert(terminalLogs);
                        return PubUtils.assignmentResult(null, 500, "数据完整性补招失败");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("解析服务器数据异常");
                }

            }
        }catch(Exception e){
            e.printStackTrace();
            return PubUtils.assignmentResult(null, 500, "Socket建立连接异常，请排查端口号，前置机信息");

        }finally{
            //一些必要的清理工作
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                in = null;
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                out = null;
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                socket = null;
            }

            //System.out.println("end---");
        }
        return PubUtils.assignmentResult(null, 200, "数据完整性补招成功");
    }

    /**
     * 完整性详情查看
     */
    @PostMapping("integralityDetail")
    @ResponseBody
    public HttpResult integralityDetail(String lineId, String startTime, String endTime, String timeType, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "integralityDetail");
        if (!StringUtils.isEmpty(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        try {
            List<IntegrityDetailVo> data = getInegDataService.getDetail(lineId,startTime,endTime,timeType);
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "获取数据完整性详情为空", "查看数据完整性列表", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(data, 200, "获取数据完整性详情为空", "查看数据完整性列表", "成功", result);
            }
        } catch (Exception e) {
            logger.error("查看数据完整性详情异常,异常为：" + e.toString());
            userLog.getLog("查看数据完整性详情", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResultLog(null, 500, "查看数据完整性详情异常", "查看数据完整性详情", "失败", result);
        }
        return result;
    }


    /**
     * 数据完整性列表-》统计分析
     */
    @PostMapping("statisticalAnalysis")
    @ResponseBody
    public HttpResult statisticalAnalysis(String startTime, String endTime, String area,Integer postType, Integer powerId, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "statisticalAnalysis");
        if (!StringUtils.isEmpty(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        try {
            List<IntegrityAnalysisData> data = deviceService.getStatisticalAnalysis(startTime,endTime,area,powerId,postType);
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "获取统计分析数据为空", "查看统计分析", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(data, 200, "获取统计分析数据成功", "查看统计分析", "成功", result);
            }
        } catch (Exception e) {
            logger.error("查看统计分析数据异常,异常为：" + e.toString());
            userLog.getLog("查看统计分析数据异常", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResultLog(null, 500, "查看统计分析数据异常", "查看统计分析", "失败", result);
        }
        return result;
    }


}
