package com.yfd.platform.modules.patroltask.controller;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.system.OsInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yfd.platform.config.AlgorithmServerConfig;
import com.yfd.platform.config.HttpServerConfig;
import com.yfd.platform.config.ParentConfig;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.constant.SystemCode;
import com.yfd.platform.modules.basedata.domain.AlgorithmModel;
import com.yfd.platform.modules.basedata.domain.SubstationDevice;
import com.yfd.platform.modules.basedata.domain.SubstationPatroldevice;
import com.yfd.platform.modules.basedata.service.IAlgorithmModelService;
import com.yfd.platform.modules.basedata.service.ISubstationDeviceService;
import com.yfd.platform.modules.basedata.service.ISubstationPatroldeviceService;
import com.yfd.platform.modules.patroltask.domain.AlarmLog;
import com.yfd.platform.modules.patroltask.domain.TaskResult;
import com.yfd.platform.modules.patroltask.domain.TaskTodo;
import com.yfd.platform.modules.patroltask.mapper.TaskResultMapper;
import com.yfd.platform.modules.patroltask.mapper.TaskTodoMapper;
import com.yfd.platform.modules.patroltask.service.IAlarmLogService;
import com.yfd.platform.utils.FileUtil;
import com.yfd.platform.utils.HttpRESTfulUtils;
import com.yfd.platform.utils.VideoToImageUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.poi.util.IOUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 智能巡视系统识别回调方法
 * </p>
 *
 * @since 2023-05-03
 */
@RestController
@RequestMapping("/")
@Slf4j
public class AnalyseCallController {

    @Resource
    private IAlarmLogService alarmLogService;

    @Resource
    private TaskResultMapper taskResultMapper;
    @Resource
    private HttpRESTfulUtils httpUtil;
    @Resource
    private HttpServerConfig Config;
    @Resource
    private ISubstationPatroldeviceService substationPatroldeviceService;
    @Resource
    private IAlgorithmModelService algorithmModelService;
    @Resource
    private AlgorithmServerConfig algorithmServerConfig;
    @Resource
    private TaskTodoMapper taskTodoMapper;
    @Resource
    private ISubstationDeviceService substationDeviceService;


    @PostMapping("/picAnalyseRetNotify")
    @ApiOperation("智能分析识别通知")
    public Object picAnalyseRetNotify(@RequestBody String params) {
        Map<String, Object> result = new HashMap<>();
        log.info("智能分析识别通知：" + params);
        try {
            boolean isJSON = JSONUtil.isTypeJSONObject(params);
            if (isJSON) {
                //正常处理
                JSONObject jsonObject = JSONUtil.parseObj(params);
                String requestId = jsonObject.getStr("requestId");//对象ID
                TaskTodo taskTodo = taskTodoMapper.selectById(requestId);
                if (ObjUtil.isNotEmpty(taskTodo)) {//日常巡视，更新巡视结果
                    alarmLogService.updateTaskResult(jsonObject);
                } else {
                    SubstationDevice substationDevice = substationDeviceService.getById(requestId);
                    if(ObjUtil.isNotEmpty(substationDevice)){
                        alarmLogService.updateDeviceResult(jsonObject);
                    }else{
                        alarmLogService.createAlarm(jsonObject);
                    }
                }
                result.put("code", SystemCode.SUCCESS_STATUS_CODE.getCode());//正常
            } else {
                result.put("code", SystemCode.REFUSE_STATUS_CODE.getCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());;
            result.put("code", "500");
        }
        return result;
    }

    @PostMapping("/silentMonitorRetNotify")
    @ApiOperation("静默监视时发现缺陷的识别通知")
    public Object silentMonitorRetNotify(@RequestBody String params) {
        Map result = new HashMap();
        try {
            boolean isJSON = JSONUtil.isTypeJSONObject(params);
            if (isJSON) {
                //正常处理
                JSONObject jsonObject = JSONUtil.parseObj(params);
                alarmLogService.createAlarm(jsonObject);

                result.put("code", SystemCode.SUCCESS_STATUS_CODE.getCode());//正常
            } else {
                result.put("code", SystemCode.REFUSE_STATUS_CODE.getCode());
            }
        } catch (Exception e) {
            result.put("code", "500");
        } finally {
            return result;
        }
    }

    @RequestMapping(value = "/snapfile", method = RequestMethod.GET)
    @ApiOperation("智能分析调用图片")
    public void getSnapImage(HttpServletResponse response, String filename) throws IOException {
        String suffix = StrUtil.subAfter(filename, ".", true).toLowerCase();
        if (!"png".equals(suffix) && !"jpg".equals(suffix) && !"gif".equals(suffix) && !"mp4".equals(suffix)) {
            throw new RuntimeException("非法文件类型");
        }
        InputStream inputStream = null;
        try {
            OsInfo osInfo = new OsInfo();
            boolean isLinux = osInfo.isLinux();
            filename = URLDecoder.decode(filename, "utf-8");
            log.info("filename" + filename);
            if (isLinux) {
                filename = StrUtil.replace(filename, "\\", "/");
            }
            String originfilename = Config.getSnapFilePath() + filename;

            inputStream = new FileInputStream(new File(originfilename));
            //set the content type and header
            response.setContentType("image/jpeg");
            if("mp4".equals(suffix)){
                response.setContentType("video/mp4");
            }
            response.setHeader("Content-Disposition", "attachment; filename=" + filename);
            //copy the file to the output stream
            IOUtils.copy(inputStream, response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            inputStream.close();
        }

    }

    @GetMapping("/previewimage")
    @ApiOperation("在线预览图片")
    @ResponseBody
    public void previewImage(HttpServletResponse response, String filename, String size, String type) throws IOException {
        OsInfo osInfo = new OsInfo();
        boolean isLinux = osInfo.isLinux();
        filename = URLDecoder.decode(filename, "utf-8");
        if (isLinux) {//linux系统替换文件路径字符
            // 000001\2023\05\15\TEST0001\CCD\20230515_152108_测试间隔2_测试主设备1_测试巡视点位1_识别.jpg
            filename = StrUtil.replace(filename, "\\", "/");
        }
        String originfilename = "";

        if (StrUtil.isNotEmpty(type) && type.equals("alarm")) {//报警显示不同目录
            originfilename = Config.getAlarmFilePath() + filename;
        } else {
            originfilename = Config.getSnapFilePath() + filename;
        }

        if (StrUtil.isNotEmpty(size) && size.equals("small")) {
            String temp = StrUtil.subBefore(originfilename, "_", true);
            String tofilename = temp + "_small.jpg";
            if (!FileUtil.exist(tofilename)) {
                Thumbnails.of(originfilename)
                        .size(80, 80)
                        .toFile(tofilename);
            }
            FileUtil.viewImage(tofilename, response);
        } else {
            FileUtil.viewImage(originfilename, response);
        }
    }

    @GetMapping("/playAudioFile")
    @ApiOperation("在线在线播放音频文件")
    @ResponseBody
    public void playAudioFile(HttpServletResponse response, String filename) throws IOException {
        OsInfo osInfo = new OsInfo();
        boolean isLinux = osInfo.isLinux();
        filename = URLDecoder.decode(filename, "utf-8");
        if (isLinux) {//linux系统替换文件路径字符
            filename = StrUtil.replace(filename, "\\", "/");
        }
        String originfilename = Config.getSnapFilePath() + filename;
        if (cn.hutool.core.io.FileUtil.exist(originfilename)) {
            FileUtil.playAudio(originfilename, response);
        }

    }

    @GetMapping("/snapandviewimage")
    @ApiOperation("截取视频流文件并预览图片")
    @ResponseBody
    public void snapandViewImage(HttpServletResponse response, String devicecode, String channelcode) throws Exception {
        String fullfilename = Config.getSnapFilePath() + "snaptemp.jpg";
        String url = String.format("rtsp://%s:%s/rtp/%s_%s", Config.getMediaIp(), Config.getMonitorRtspPort(),
                devicecode, channelcode);
        List<SubstationPatroldevice> list =
                substationPatroldeviceService.list(new LambdaQueryWrapper<SubstationPatroldevice>().eq(SubstationPatroldevice::getInternationalId, devicecode));
        if (list.size() <= 0) {
            return;
        }
        SubstationPatroldevice substationPatroldevice = list.get(0);
        if ("15".equals(substationPatroldevice.getType())) {
            List<Map<String, Object>> dockInfoBySn =
                    substationPatroldeviceService.getDockInfoBySn(substationPatroldevice.getInternationalId());
            if (dockInfoBySn.size() > 0) {
                Map<String, Object> map = dockInfoBySn.get(0);
                url = "rtmp://"+Config.getPatrolIp()+":1935" + map.get("dronePushUrl").toString();
            }
        }
        if ("dali".equals(substationPatroldevice.getManufacturer())) {
            String channelinfo = substationPatroldevice.getChannelinfo();
            if (!JSONUtil.isTypeJSONArray(channelinfo)) {
                return;
            }
            JSONArray jsonArray = JSONUtil.parseArray(channelinfo);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if ("2".equals(jsonObject.getStr("channel_type"))) {
                    url = jsonObject.getStr("channel_rtspurl");
                }
            }
        }
        VideoToImageUtil.getVideoPicture(Config.getffmpegPath(), url, fullfilename);
        FileUtil.viewImage(fullfilename, response);
    }

    private String getToken() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOnce("Username", algorithmServerConfig.getUsername());
        jsonObject.putOnce("Password", algorithmServerConfig.getPassword());
        com.alibaba.fastjson.JSONObject responseData = httpUtil.sendHttpPost("json",
                algorithmServerConfig.getServerIp(), algorithmServerConfig.getHttpPort(), "", "recogApi/token",
                jsonObject, null);
        if (!"200".equals(responseData.getString("code"))) {
            return null;
        }
        return responseData.getString("Token");
    }

    @PostMapping("/algorithmUpdateResult")
    @ApiOperation("分析主机返回模型上传结果")
    public void algorithmUpdateResult(@RequestBody String params) {
        JSONObject jsonObject = JSONUtil.parseObj(params);
        String requestId = jsonObject.getStr("requestId");
        LambdaUpdateWrapper<AlgorithmModel> updateWrapper1 = new LambdaUpdateWrapper<>();
        updateWrapper1.set(AlgorithmModel::getRunstate, "1").set(AlgorithmModel::getRunstate, "0");
        algorithmModelService.update(updateWrapper1);
        LambdaUpdateWrapper<AlgorithmModel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AlgorithmModel::getId, requestId).set(AlgorithmModel::getRunstate, "1");
        algorithmModelService.update(updateWrapper);
//        AlgorithmModel algorithmModel = algorithmModelService.getById(requestId);
//        JSONObject jsonObject1 = new JSONObject();
//        jsonObject1.putOnce("sectionId", algorithmModel.getSectionId());
//        jsonObject1.putOnce("stationId", algorithmModel.getStationId());
//        jsonObject1.putOnce("version", algorithmModel.getVersion());
//        String token = getToken();
//        httpUtil.sendHeaderHttpPost("json", algorithmServerConfig.getServerIp(), algorithmServerConfig.getHttpPort(), "", token,
//                "recogApi/updateAlgorithmVersion", jsonObject1, null);
    }
}
