package com.ruoyi.zhdd.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.zhdd.service.IDhService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO
 * @Author: huangcheng
 * @Date: 2022/1/19
 * @Version V1.0
 */
@Service
@Slf4j
public class DhServiceImpl implements IDhService {

    @Value("${third.dhAuthorize}")
    private String dhAuthorizeUrl;
    @Value("${third.keepalive}")
    private String keepaliveUrl;
    @Value("${third.dhDeviceTree}")
    private String dhDeviceTreeUrl;
    @Autowired
    private ISysConfigService sysConfigService;

    @Override

    public String getToken() {
        String token = RedisUtils.getCacheObject(Constants.CACHE_DH_TOKEN);
        if (token == null) {
            token = authorize();
        }
        return token;
    }

    /**
     * 创建会话
     *
     * @return
     */
    public String authorize() {
        // 从大华接口获取token
        String token = "";
        String userName = "shujuceshi";
        JSONObject jsonOne = new JSONObject();
        jsonOne.set("userName", userName);
        jsonOne.set("clientType", "other");
        String postOne = "";
        try {
            postOne = HttpUtil.post(dhAuthorizeUrl, jsonOne.toString());
        } catch (Exception e) {
            log.error("大华接口请求异常：{}", e.getMessage());
            throw new ServiceException("大华接口请求异常");
        }
        JSONObject postOneJson = JSONUtil.parseObj(postOne);
        if (postOneJson.containsKey("realm")) {
            String randomKey = postOneJson.getStr("randomKey");
            String realm = postOneJson.getStr("realm");
            String encryptType = postOneJson.getStr("encryptType");
            // 第二次交互
            String password = "Admin123";
            String signature = SecureUtil.md5(
                SecureUtil.md5(userName + ":" + realm + ":" +
                    SecureUtil.md5(
                        SecureUtil.md5(
                            userName +
                                SecureUtil.md5(password)))) + ":" + randomKey);
            jsonOne.set("signature", signature);
            jsonOne.set("randomKey", randomKey);
            jsonOne.set("encryptType", encryptType);
            jsonOne.set("expiredTime", 86400);
            String postTwo = HttpUtil.post(dhAuthorizeUrl, jsonOne.toString());
            JSONObject postTwoJson = JSONUtil.parseObj(postTwo);
            if (postTwoJson.containsKey("token")) {
                token = postTwoJson.getStr("token");
                int duration = postTwoJson.getInt("duration");
                log.info("大华创建会话的过期时间：{}", duration);
                if (ObjectUtil.isEmpty(duration)) {
                    duration = 120;
                }
                // 存入redis缓存
                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN, token, Convert.toInt(duration * 0.7), TimeUnit.SECONDS);
//                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN_REFRESH, token);
            } else {
                log.error("大华=第二次创建会话失败：{}", postTwoJson);
                if ("user is repeated landing".equals(postTwoJson.getStr("message"))) {
                    // 说明已经登录过，那么退出，重新获取

                }
            }
        } else {
            log.error("大华=第一次创建会话失败：{}", postOneJson);
        }
        return token;
    }

    /**
     * 保活大华token
     *
     * @param token
     */
    public void tokenKeepalive(String token) {
        JSONObject json = new JSONObject();
        json.set("token", token);
        json.set("duration", 120);
        String put = HttpRequest.put(keepaliveUrl).timeout(-1).body(json.toString()).execute().body();
        JSONObject putJson = JSONUtil.parseObj(put);
        if (putJson.getInt("code") == 200) {
            // 存入redis缓存
            RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN, token, 120, TimeUnit.SECONDS);
        } else {
            log.info("保活失败：{}。重新获取", putJson);
            authorize();
        }
    }

    @Override
    public Object getDeviceTree() {
        Map<String, Object> param = new HashMap<>();
        String id = sysConfigService.selectConfigByKey("dh.device.orgId");
        param.put("id", id);
        JSONArray list = getList(param);
        JSONArray newList = new JSONArray();
        if (list != null && list.size() > 0) {
            for (Object o : list) {
                JSONObject getJson = JSONUtil.parseObj(o);
                if (id.equals(getJson.getStr("orgCode")) && getJson.getInt("nodeType") == 1) {
                    param.put("id", getJson.getStr("id"));
                    JSONArray listTwo = getList(param);
                    if (listTwo != null && listTwo.size() > 0) {
                        for (Object two : listTwo) {
                            newList.add(JSONUtil.parseObj(two));
                        }
                    }
                }
                newList.add(getJson);
            }
        }
        log.info("数量：{}", newList.size());
        return newList;
    }

    @Override
    public JSONArray querySingleStat() {
        Map<String, Object> param = new HashMap<>();
        param.put("orgCode", "S4NbecfYB1DGB68AN187Q8");
        param.put("isSubOrg", 1);
        param.put("page", 1);
        param.put("pageSize", 3000);
        String get = "";
        try {
            get = HttpRequest.get("http://10.55.134.3:8314/videoService/devicesManager/searchDevices")
                .header("X-Subject-Token", this.getToken())
                .form(param)
                .timeout(-1)
                .execute().body();
        } catch (Exception e) {
            log.error("大华单兵设备状态请求异常：{}", e.getMessage());
            return new JSONArray();
        }
        JSONObject getJson = JSONUtil.parseObj(get);
        if (getJson.containsKey("code")) {
            // 说明有错误
            log.error("获取大华单兵设备状态出错：{}", getJson);
            return new JSONArray();
        }
        return getJson.getJSONArray("results");
    }

    private JSONArray getList(Map<String, Object> param) {
        param.put("nodeType", 1);
        param.put("typeCode", "01;0;ALL;ALL");
        param.put("page", 1);
        param.put("pageSize", 3000);
        String get = "";
        try {
            get = HttpRequest.get(dhDeviceTreeUrl)
                .header("X-Subject-Token", this.getToken())
                .form(param)
                .timeout(-1)
                .execute().body();
        } catch (Exception e) {
            log.error("大华接口2请求异常：{}", e.getMessage());
            throw new ServiceException("大华接口请求异常");
        }
        JSONObject getJson = JSONUtil.parseObj(get);
        if (getJson.containsKey("code")) {
            // 说明有错误
            log.error("获取设备树出错：{}", getJson);
            throw new ServiceException("获取设备树出错.稍后再试");
        }
        return getJson.getJSONArray("results");
    }

    public static void main(String[] args) {
        /*String token = "";
        String userName = "shujuceshi";
        JSONObject jsonOne = new JSONObject();
        jsonOne.set("userName", userName);
        jsonOne.set("clientType", "other");
        String postOne = HttpUtil.post("http://10.211.55.3:6699/videoService/accounts/authorize", jsonOne.toString());
        JSONObject postOneJson = JSONUtil.parseObj(postOne);
        if (postOneJson.containsKey("realm")) {
            String randomKey = postOneJson.getStr("randomKey");
            String realm = postOneJson.getStr("realm");
            String encryptType = postOneJson.getStr("encryptType");
            // 第二次交互
            String password = "Admin123";
            String signature = SecureUtil.md5(
                SecureUtil.md5(userName + ":" + realm + ":" +
                    SecureUtil.md5(
                        SecureUtil.md5(
                            userName +
                                SecureUtil.md5(password)))) + ":" + randomKey);
            jsonOne.set("signature", signature);
            jsonOne.set("randomKey", randomKey);
            jsonOne.set("encryptType", encryptType);
            String postTwo = HttpUtil.post("http://10.211.55.3:6699/videoService/accounts/authorize", jsonOne.toString());
            JSONObject postTwoJson = JSONUtil.parseObj(postTwo);
            if (postTwoJson.containsKey("token")) {
                token = postTwoJson.getStr("token");
                // 存入redis缓存
//                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN, token, 120, TimeUnit.SECONDS);
//                RedisUtils.setCacheObject(Constants.CACHE_DH_TOKEN_REFRESH, token);
            } else {
                log.error("大华=第二次创建会话失败：{}", postTwoJson);
                if ("user is repeated landing".equals(postTwoJson.getStr("message"))) {
                    // 说明已经登录过，那么退出，重新获取

                }
            }
        } else {
            log.error("大华=第一次创建会话失败：{}", postOneJson);
        }
        System.out.println(token);*/
    }

}
