package com.zhgd.xmgl.util;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hikvision.artemis.sdk.Client;
import com.hikvision.artemis.sdk.Request;
import com.hikvision.artemis.sdk.Response;
import com.hikvision.artemis.sdk.constant.Constants;
import com.hikvision.artemis.sdk.enums.Method;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.util.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @program: wisdomSite
 * @description: 海康ISC视频接口
 * @author: Mr.Peng
 * @create: 2020-11-20 10:18
 **/
@Slf4j
public class HikVideoUtil {

    private static final String ARTEMIS_PATH = "/artemis";

    /**
     * @param cameraIndexCode 监控点
     * @param type            取流协议  rtsp、rtmp、hls
     * @param streamType      码流类型：子码流主码流
     * @param Ip
     * @param port
     * @param appke
     * @param appSecret
     * @return
     */
    public static String callPostApiGetPreviewURL(String cameraIndexCode, String type, Integer streamType, String Ip, String port, String appke, String appSecret) {
        String url = null;
        final String getCamsApi = ARTEMIS_PATH + "/api/video/v1/cameras/previewURLs";
        Map<String, Object> paramMap = new HashMap<String, Object>();// post请求Form表单参数
        paramMap.put("cameraIndexCode", cameraIndexCode);
        //1:子码流，0:主码流
        if (streamType == null) {
            streamType = 1;
        }
        if (streamType == 2) {
            streamType = 0;
        }
        paramMap.put("streamType", streamType);
        paramMap.put("protocol", StringUtils.isNotEmpty(type) ? type : "hls");
        paramMap.put("expand", "streamform=rtp");
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, body, null, null, "application/json", appke, appSecret);
        log.info(result);
        if (result != null && result.length() > 0) {
            JSONObject json = JSONObject.parseObject(result);
            if ("0".equals((String) json.get("code"))) {
                JSONObject object2 = (JSONObject) json.get("data");
                url = (String) object2.get("url");
            }
        } else {
            throw new OpenAlertException(MessageUtil.get("failErr"));
        }
        return url;
    }

    public static String setSubscriptionByEvent(String backUrl, String Ip, String port, String appke, String appSecret, Integer[] eventTypes) {
        String message = null;
        final String getCamsApi = ARTEMIS_PATH + "/api/eventService/v1/eventSubscriptionByEventTypes";
        // post请求Form表单参数
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //设置温度报警、烟雾检测两个事件
        //Integer[] eventTypes={ 192517,192513};
        paramMap.put("eventTypes", eventTypes);
        paramMap.put("eventDest", backUrl);
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, body, null, null, "application/json", appke, appSecret);
        log.info(result);
        if (result != null && result.length() > 0) {
            JSONObject json = JSONObject.parseObject(result);
            if ("0".equals((String) json.get("code"))) {
                message = "success";
            } else {
                throw new OpenAlertException((String) json.get("msg"));
            }
        } else {
            throw new OpenAlertException(MessageUtil.get("failErr"));
        }
        return message;
    }

    //查询事件
    public static String eventSubscriptionView(String Ip, String port, String appke, String appSecret) {
        String message = null;
        final String getCamsApi = ARTEMIS_PATH + "/api/eventService/v1/eventSubscriptionView";
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, null, null, null, "application/json", appke, appSecret);
        log.info(result);
        if (result != null && result.length() > 0) {
            JSONObject json = JSONObject.parseObject(result);
            if ("0".equals((String) json.get("code"))) {
                message = "success";
            } else {
                throw new OpenAlertException((String) json.get("msg"));
            }
        } else {
            throw new OpenAlertException(MessageUtil.get("failErr"));
        }
        return message;
    }

    //取消事件
    public static String eventUnSubscriptionByEventTypes(String Ip, String port, String appke, String appSecret) {
        String message = null;
        final String getCamsApi = ARTEMIS_PATH + "/api/eventService/v1/eventUnSubscriptionByEventTypes";
        // post请求Form表单参数
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //设置温度报警、烟雾检测两个事件
        Integer[] eventTypes = {131331};
        paramMap.put("eventTypes", eventTypes);
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, body, null, null, "application/json", appke, appSecret);
        log.info(result);
        if (result != null && result.length() > 0) {
            JSONObject json = JSONObject.parseObject(result);
            if ("0".equals((String) json.get("code"))) {
                message = "success";
            } else {
                throw new OpenAlertException((String) json.get("msg"));
            }
        } else {
            throw new OpenAlertException(MessageUtil.get("failErr"));
        }
        return message;
    }

    /**
     * 海康视频控球
     *
     * @param cameraIndexCode 监控点
     * @param action          0-开始 ，1-停止
     * @param command         操作，如左转、下转、焦距变大、焦点后移、光圈缩小……等操作
     * @param speed           云台速度
     * @param Ip              海康服务接口IP地址
     * @param port            海康服务接口端口
     * @param appke           海康APPkey
     * @param appSecret       海康appSecret
     * @return
     */
    public static boolean getPtzControl(String cameraIndexCode, Integer action, String command, Integer speed, String Ip, String port, String appkey, String appSecret) {
        String getCamsApi = ARTEMIS_PATH + "/api/video/v1/ptzs/controlling";
        Map<String, Object> paramMap = new HashMap<String, Object>();// post请求Form表单参数
        paramMap.put("cameraIndexCode", cameraIndexCode);
        paramMap.put("action", action);
        paramMap.put("command", command);
        paramMap.put("speed", speed);
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        log.info("===========:" + body);
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, body, null, null, "application/json", appkey, appSecret);
        log.info(result);
        if (result != null && result.length() > 0) {
            JSONObject json = JSONObject.parseObject(result);
            if ("0".equals((String) json.get("code"))) {
                return true;
            } else {
                throw new OpenAlertException(MessageUtil.get("ptzOperationFail"));
            }
        } else {
            throw new OpenAlertException(MessageUtil.get("failErr"));
        }
    }

    public static String doPostStringArtemis(String host, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType, String appKey, String appSecret) {
        String httpSchema = (String) path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;

            try {
                Map<String, String> headers = new HashMap();
                if (StringUtils.isNotBlank(accept)) {
                    headers.put("Accept", accept);
                } else {
                    headers.put("Accept", "*/*");
                }

                if (StringUtils.isNotBlank(contentType)) {
                    headers.put("Content-Type", contentType);
                } else {
                    headers.put("Content-Type", "application/text;charset=UTF-8");
                }

                Request request = new Request(Method.POST_STRING, httpSchema + host, path.get(httpSchema), appKey, appSecret, Constants.DEFAULT_TIMEOUT);
                request.setHeaders(headers);
                request.setQuerys(querys);
                request.setStringBody(body);
                Response response = Client.execute(request);
                responseStr = getResponseResult(response);
            } catch (Exception var10) {
                var10.printStackTrace();
            }

            return responseStr;
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    private static String getResponseResult(Response response) {
        String responseStr = null;
        int statusCode = response.getStatusCode();
        if (!String.valueOf(statusCode).startsWith("2") && !String.valueOf(statusCode).startsWith("3")) {
            //String msg = response.getErrorMessage();
            responseStr = response.getBody();
        } else {
            responseStr = response.getBody();
        }

        return responseStr;
    }

    public static String callPostApiGetCamerasWithCode(String host, String indexCode, Integer pageNo, String appKey, String appSecret) {
        String result = null;
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            final String getCamsApi = ARTEMIS_PATH + "/api/resource/v1/regions/regionIndexCode/cameras";
            Map<String, Object> paramMap = new HashMap<String, Object>();// post请求Form表单参数
            paramMap.put("regionIndexCode", indexCode);
            paramMap.put("pageNo", pageNo);
            paramMap.put("pageSize", 100);
            String body = JSON.toJSON(paramMap).toString();
            Map<String, String> path = new HashMap<String, String>(3) {
                {
                    put("https://", getCamsApi);
                }
            };
            result = doPostStringArtemis(host, path, body, null, null, "application/json", appKey, appSecret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取监控点列表
     *
     * @param indexCode
     * @param Ip
     * @param port
     * @param appKey
     * @param appSecret
     * @return
     */
    public static List<Map<String, Object>> getCamerasInfoList(String indexCode, String Ip, String port, String appKey, String appSecret) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            String host = Ip + ":" + port;
            Integer pageNo = 1;
            boolean temp = true;
            while (temp) {
                String result = callPostApiGetCamerasWithCode(host, indexCode, pageNo, appKey, appSecret);
                if (result != null && result.length() > 0) {
                    JSONObject json = JSONObject.parseObject(result);
                    if ("0".equals((String) json.get("code"))) {
                        Map<String, Object> map = JSONUtil.readValueToMap(json.get("data").toString());
                        List<Map<String, Object>> tempList = (List<Map<String, Object>>) map.get("list");
                        list.addAll(tempList);
                        Integer total = Integer.parseInt(map.get("total").toString());
                        if (total <= (((pageNo - 1) * 100) + tempList.size())) {
                            temp = false;
                        }
                        pageNo++;
                    } else {
                        temp = false;
                    }
                } else {
                    temp = false;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取组织区域列表
     *
     * @param Ip
     * @param port
     * @param appKey
     * @param appSecret
     * @return
     */
    public static String getRegions(String Ip, String port, String appKey, String appSecret) {
        String indexCode = null;
        try {
            String host = Ip + ":" + port;
            final String getCamsApi = ARTEMIS_PATH + "/api/resource/v1/regions";
            Map<String, String> paramMap = new HashMap<String, String>();// post请求Form表单参数
            paramMap.put("pageNo", "1");
            paramMap.put("pageSize", "1000");
            String body = JSON.toJSON(paramMap).toString();
            Map<String, String> path = new HashMap<String, String>(2) {
                {
                    put("https://", getCamsApi);
                }
            };
            String result = doPostStringArtemis(host, path, body, null, null, "application/json", appKey, appSecret);
            /*if(result!=null&&result.length()>0){
                JSONObject json=JSONObject.parseObject(result);
                if("0".equals((String) json.get("code"))){
                    JSONObject object2=(JSONObject) json.get("data");
                    indexCode=(String) object2.get("indexCode");
                }
            }*/
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return indexCode;
    }

    /**
     * 获取监控点回放取流URL
     *
     * @return
     */
    public static String callPostPlaybackURLs(String cameraIndexCode, String recordLocation, String protocol, Integer transmode, Date beginTime, Date endTime, String uuid, String Ip, String port, String appke, String appSecret) {
        String url = null;
        final String playbackURLs = ARTEMIS_PATH + "/api/video/v1/cameras/playbackURLs";
        Map<String, Object> paramMap = new HashMap<String, Object>();// post请求Form表单参数
        paramMap.put("cameraIndexCode", cameraIndexCode);
        paramMap.put("recordLocation", StringUtils.isNotEmpty(recordLocation) ? recordLocation : "1");
        paramMap.put("protocol", StringUtils.isNotEmpty(protocol) ? protocol : "rtsp");
        paramMap.put("transmode", transmode != null ? transmode : 1);
//        paramMap.put("beginTime", beginTime != null ? beginTime : new Date());
        paramMap.put("beginTime", DateUtil.format(DateUtil.offsetDay(new Date(), -2), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
        paramMap.put("endTime", DateUtil.format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
        paramMap.put("uuid", StringUtils.isNotEmpty(uuid) ? uuid : "");
        paramMap.put("expand", "streamform=rtp");
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", playbackURLs);
            }
        };
        String host = Ip + ":" + port;
        String result = doPostStringArtemis(host, path, body, null, null, "application/json", appke, appSecret);
        log.info(result);
//        if (result != null && result.length() > 0) {
//            JSONObject json = JSONObject.parseObject(result);
//            if ("0".equals((String) json.get("code"))) {
//                JSONObject object2 = (JSONObject) json.get("data");
//                url = (String) object2.get("url");
//            }
//        } else {
//            throw new OpenAlertException(MessageUtil.get("failErr"));
//        }
        return url;
    }


    //String cameraIndexCode,String type,Integer streamType,String Ip,String port,String appke,String appSecret
//    public static void main(String[] args) {
//        String url= HikVideoUtil.callPostApiGetPreviewURL("937f589bbdf1447b880858118c42f9a9","hls",
//                1,"124.71.141.90","443","25808144","jlMfG3CdEDwwcDG1So4U");
//        log.info(url);
//        //setSubscriptionByEvent("http://183.95.84.34:7185/api/videoCallback/videoSubscriptionEvent","183.95.84.53","4443","21995826","JrxywCchW333Al5huAAl");
//        //eventUnSubscriptionByEventTypes("183.95.84.53","4443","21995826","JrxywCchW333Al5huAAl");
//        //String data=eventSubscriptionView("124.71.141.90","443","25808144","jlMfG3CdEDwwcDG1So4U");
//        //log.info(data);
//    }

    public static void main(String[] args) {
//        String url = HikVideoUtil.callPostApiGetPreviewURL("937f589bbdf1447b880858118c42f9a9", "hls",
//                1, "124.71.141.90", "443", "25808144", "jlMfG3CdEDwwcDG1So4U");


        HikVideoUtil.callPostPlaybackURLs("d8faac02f7f94e879f79472e7ac3fee5", null,
                null, null, null, null, "", "182.101.141.23", "18443", "24017757", "VJz0FbzmE6drPQ7egsBi");
        //setSubscriptionByEvent("http://183.95.84.34:7185/api/videoCallback/videoSubscriptionEvent","183.95.84.53","4443","21995826","JrxywCchW333Al5huAAl");
        //eventUnSubscriptionByEventTypes("183.95.84.53","4443","21995826","JrxywCchW333Al5huAAl");
        //String data=eventSubscriptionView("124.71.141.90","443","25808144","jlMfG3CdEDwwcDG1So4U");
        //log.info(data);
    }

}
