package com.yfd.platform.modules.patroltask.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfd.platform.component.nettyudpserver.NettyUdpServer;
import com.yfd.platform.config.HttpServerConfig;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.basedata.domain.SubstationDevice;
import com.yfd.platform.modules.basedata.service.ISubstationDeviceService;
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.service.DockTaskService;
import com.yfd.platform.modules.patroltask.service.ITaskTodoService;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import com.yfd.platform.utils.FileUtil;
import com.yfd.platform.utils.HttpRESTfulUtils;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Date: 2024/7/5 13:52
 * @Description:
 */
@Service
@Transactional
@Slf4j
public class DockTaskServiceImpl implements DockTaskService {

    @Resource
    private ITaskTodoService taskTodoService;
    @Resource
    private ISubstationDeviceService substationDeviceService;
    @Resource
    private TaskResultMapper taskResultMapper;
    @Resource
    private HttpServerConfig httpServerConfig;
    @Resource
    private ISysDictionaryItemsService sysDictionaryItemsService;
    @Resource
    private HttpRESTfulUtils httpUtil;

    /**********************************
     * 用途说明: 保存无人机文件
     * 参数说明 jobId
     * 参数说明 fileName
     * 参数说明 url
     * 返回值说明: void
     ***********************************/
    @Override
    public ResponseResult saveMediaFile(String jobId, String fileName, String url) throws Exception {
        // 判断当前jobId是否存在
        TaskTodo taskTodo = taskTodoService.getById(jobId);
        if (taskTodo == null) {
            return ResponseResult.error();
        }
        String[] split = fileName.replace(".jpeg", "").split("_");
        if (split.length <= 0) {
            return ResponseResult.error();
        }
        String deviceName = split[split.length - 1];
        LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskResult::getDeviceName, deviceName).eq(TaskResult::getTaskTodoId, jobId);
        List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
        if (taskResultList.size() <= 0) {
            return ResponseResult.error();
        }
        TaskResult taskResult = taskResultList.get(0);
        String flag = taskResult.getFlag();
        if (!"0".equals(flag)) {
            return ResponseResult.success();
        }
        String filetype = "CCD";
        String fileType = taskResult.getFileType();
        if (ObjectUtil.isNotEmpty(fileType)) {
            switch (fileType) {
                case "1":
                    filetype = "FIR";
                    break;
                case "3":
                    filetype = "Audio";
                    break;
                case "4":
                    filetype = "Video";
                    break;
                default:
                    filetype = "CCD";
                    break;
            }
        }
        String filepath = String.format("%s/%s/%s/%s/%s/%s/",
                taskResult.getStationCode(),
                DateUtil.format(DateUtil.date(), "yyyy"),
                DateUtil.format(DateUtil.date(), "MM"),
                DateUtil.format(DateUtil.date(), "dd"),
                taskResult.getTaskCode(),
                filetype
        );
        //文件命名格式为：日期_时间_间隔名_设备名_点位名_类型.jpg
//        String filename = String.format("%s_%s_%s_%s_%s_%s.jpg",
//                DateUtil.format(DateUtil.date(), "yyyyMMdd"),
//                DateUtil.format(DateUtil.date(), "HHmmss"),
//                taskResult.getBayName(),
//                taskResult.getMainDeviceName(),
//                taskResult.getDeviceName(),
//                "原图"
//        );
        String filename = String.format("%s_%s_%s.jpg",
                taskResult.getDeviceId(),
                taskResult.getPatroldeviceCode(),
                DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss")
        );
        FileUtil.downloadFile(url, httpServerConfig.getSnapFilePath() + filepath, filename);
        Thread.sleep(3000);
        String fullfilename = filepath + filename;
        //转码存储
        fullfilename = URLEncoder.encode(fullfilename, "utf-8");
        taskResult.setFilePath(fullfilename);
        Integer integer = taskResultMapper.selectCount(new LambdaQueryWrapper<TaskResult>().eq(TaskResult::getTaskTodoId, taskTodo.getTaskTodoId()).ne(TaskResult::getFlag, "0"));
        taskTodoService.updateTaskResultStatus(taskResult.getTaskTodoId(), taskResult.getResultId(), fullfilename, "1");
        log.info("------------------总数" + taskTodo.getDeviceSumnum() + "------当前巡视数量" + integer);
        if (integer == (taskTodo.getDeviceSumnum() - 1)) {
            // 下载完图片调用分析主机
            new Thread(() -> {
                try {
                    this.callPicAnalyse(taskTodo);
                } catch (Exception e) {
                    log.error(e.getMessage());;
                }
            }
            ).start();
        }


        return ResponseResult.success();
    }

    @Override
    public void sendTaskResultData(String taskTodoId) throws Exception {
        TaskTodo taskTodo = taskTodoService.getById(taskTodoId);
        this.callPicAnalyse(taskTodo);
    }

    /**********************************
     * 用途说明: 调用分析主机
     * 参数说明 taskResult
     * 参数说明 taskTodo
     * 返回值说明: void
     ***********************************/
    private void callPicAnalyse(TaskTodo taskTodo) throws Exception {
        List<TaskResult> taskResults = taskResultMapper.selectList(new LambdaQueryWrapper<TaskResult>().eq(TaskResult::getTaskTodoId, taskTodo.getTaskTodoId()));
        for (TaskResult taskResult : taskResults) {
            Thread.sleep(10000);
            String flag = taskResult.getFlag();
            if ("4".equals(flag)) {
                continue;
            }
            String deviceId = taskResult.getDeviceId();
            //排除当前时刻需要检修的巡视点
            int count = taskTodoService.queryExaminePlan(deviceId, taskTodo.getPlanStartTime());
            if (count > 0) {
                //更新当前记录状态，修改为  3:设备检修中
                taskTodoService.updateTaskResultStatus(taskTodo.getTaskTodoId(), taskResult.getResultId(),
                        "", "3");
                //跳过设备检修区间对应的巡视点
                continue;
            }
            SubstationDevice substationDevice = substationDeviceService.getById(deviceId);
            //获取typelist 识别类型
            String pictureAnalysisTypeList = substationDevice.getPictureAnalysisTypeList();
            JSONArray typelist = new JSONArray();
            String analysePort = httpServerConfig.getAnalysePort11();
            JSONObject callresult = null;
            JSONObject customParams = new JSONObject();
            if (StrUtil.isNotEmpty(pictureAnalysisTypeList)) {
                JSONObject jobj = JSON.parseObject(pictureAnalysisTypeList);
                if (ObjectUtil.isNotEmpty(jobj.getString("PictureAnalysisType"))) {
//                if ("meter".equals(jobj.getString("PictureAnalysisType"))) {
//                    typelist.add(substationDevice.getOutsideFeature());
//                } else {
//                    typelist.add(jobj.getString("PictureAnalysisType"));
//                }
                    if ("meter".equals(jobj.getString("PictureAnalysisType"))) {
                        customParams.put("meterType", substationDevice.getOutsideFeature());
                    }
                    typelist.add(jobj.getString("PictureAnalysisType"));
                }

                if (ObjectUtil.isNotEmpty(jobj.getString("PictureDefectAnalysisType"))) {
                    analysePort = httpServerConfig.getAnalysePort12();
                    JSONArray typeresult = new JSONArray();
                    String[] PictureDefectAnalysisTypes = jobj.getString("PictureDefectAnalysisType").split(",");
                    for (String pictureDefectAnalysisType : PictureDefectAnalysisTypes) {
                        LambdaQueryWrapper<SysDictionaryItems> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(SysDictionaryItems::getDictId, "fedeb076ef96422eee01c88d7f7efd4e").eq(SysDictionaryItems::getItemCode, pictureDefectAnalysisType); //缺陷类别字典
                        queryWrapper.select(SysDictionaryItems::getItemCode,
                                SysDictionaryItems::getDictName, SysDictionaryItems::getCustom1,
                                SysDictionaryItems::getCustom2);
                        SysDictionaryItems item = sysDictionaryItemsService.getOne(queryWrapper);
                        if (StrUtil.isNotEmpty(item.getCustom1()) && JSONUtil.isTypeJSONArray(item.getCustom1())) {
                            //确认一下是否是这个字段
                            typeresult.addAll(JSONUtil.parseArray(item.getCustom1()));
                        }

                    }
                    if (typeresult.size() > 0) {
                        //缺陷识别结果类型
                        customParams.put("defectresulttypes", typeresult);
                    }
                    List<String> pictureType = StrUtil.split(jobj.getString(
                            "PictureDefectAnalysisType"), ",");
                    List<Map<String, Object>> pictureDefectAnalysisType =
                            sysDictionaryItemsService.getDeviceByType("PictureDefectAnalysisType");
                    // 获取到子项
                    List<String> itemCodeList =
                            pictureDefectAnalysisType.stream().filter(p -> pictureType.contains(p.get("itemcode").toString())).map(m -> m.get("custom1").toString()).collect(Collectors.toList());
                    for (String code : itemCodeList) {
                        JSONArray jsonArray = JSONUtil.parseArray(code);
                        List<String> keyList =
                                jsonArray.stream().map(j -> JSONUtil.parseObj(j).getStr("key")).collect(Collectors.toList());
                        typelist.addAll(keyList);
                    }
                }
                if (ObjectUtil.isNotEmpty(jobj.getString("PictureDiscriminateAnalysisType"))) {
                    typelist.add(jobj.getString("PictureDiscriminateAnalysisType"));
                    analysePort = httpServerConfig.getAnalysePort12();
                }
            }
            if (typelist.size() == 0) {
                throw new Exception("未设置识别方式，不能进行图形识别！");
            }

            // 1、 调用图片识别算法，进行图形识别
            //表计类型
            if (ObjectUtil.isNotEmpty(substationDevice.getMeterType())) {
                customParams.put("meterType", substationDevice.getMeterType());
            }
            if (ObjectUtil.isNotEmpty(substationDevice.getOutsideAngle())) {
                if (JSONUtil.isTypeJSONArray(substationDevice.getOutsideAngle())) {
                    JSONArray jsonArray = JSONUtil.parseArray(substationDevice.getOutsideAngle());
                    customParams.put("TempAngleList", jsonArray);
                }

            }


            //基准图
            if (ObjUtil.isNotEmpty(taskResult.getPatroldeviceBaseimage())) {
                String path = URLEncoder.encode(taskResult.getPatroldeviceBaseimage(), "utf-8");
                String imageurl = String.format("http://%s:%s/%s/snapNormalFile?filename=%s",
                        httpServerConfig.getPatrolIp(), httpServerConfig.getPatrolPort(),
                        httpServerConfig.getPatrolAppname(),
                        path);
                customParams.put("imageNormalUrlPath", imageurl);
            }
            //有效识别区域
            if (ObjUtil.isNotEmpty(taskResult.getPatroldeviceBaseimage())) {
                customParams.put("effectiveregion", taskResult.getPatroldeviceBaseimage());
            }
            log.info("==============================typelist=======================" + typelist.toString());
            log.info("customParams：" + JSONUtil.toJsonStr(customParams));
            String imgDecode = URLDecoder.decode(taskResult.getFilePath(), "utf-8");
            callresult = httpUtil.callPicAnalyse(taskResult.getTaskTodoId(), taskResult.getResultId(), JSONUtil.toJsonStr(typelist), JSONUtil.toJsonStr(customParams), imgDecode);

//            if (callresult != null) {
//                String code = callresult.get("code").toString();
//                if ("-2".equals(code) || "201".equals(code)) {
//                    // 设置请求分析主机调用失败的任务为巡视失败
//                    taskTodoService.setTaskResultAndTodo(taskTodo.getStationCode(), taskResult.getResultId(),
//                            taskTodo.getDeviceSumnum(), taskTodo.getTaskTodoId());
//                }
//            }
        }

    }
}
