package com.zcloud.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zcloud.entity.PageData;
import com.zcloud.service.corp.CorpPlsInfoService;
import com.zcloud.service.system.UsersService;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author fangjiakai
 * @date 2024/11/28 16:36
 */
@Component
public class PLSGroupUtil {
    private static final Logger logger = LoggerFactory.getLogger(PLSGroupUtil.class);
    private static CorpPlsInfoService corpplsinfoService;
    private static UsersService usersService;
    // 后台地址
    public static HashMap<String, String> BAKEADDR = new HashMap<>();
    private static RestTemplate restTemplate;

    public static JSONObject GeneralGetById(String Url, Object id, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + Url + id, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static Object getRyRegionInfo(String corpinfoId, int id) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(corpinfoId));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(corpinfoId) + "/deploy/region/" + id, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static JSONObject getAlArmDataList(String CORPINFO_ID, int currentPage, int showCount, String s, int status, int eleType) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + "/deploy/alarm/list?eleType=" + eleType + "&status=" + status + "&pageNum=" + currentPage + "&pageSize=" + showCount + "&str=", HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static JSONObject GeneralList(String Url, PageData pageData) throws Exception {
        String params = buildGetParams(JSONObject.parseObject(JSON.toJSONString(pageData)));
        String CORPINFO_ID = Jurisdiction.getCORPINFO_ID();
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + Url + params, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static String buildGetParams(Map<String, Object> params) throws Exception {
        StringBuilder sb = new StringBuilder();
        sb.append("?");
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (sb.length() > 1) {
                sb.append("&");
            }
            String key = entry.getKey();
            if ("currentPage".equals(entry.getKey())) key = "pageNum";
            if ("showCount".equals(entry.getKey())) key = "pageSize";
            sb.append(URLEncoder.encode(key, StandardCharsets.UTF_8.toString()));
            sb.append("=");
            sb.append(entry.getValue());
        }
        return sb.toString();
    }

    public static JSONObject GetGeneral(String url, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + url, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static boolean determineWhetherThePersonIsInTheElectronicFence(String CORPINFO_ID, Integer PLS_ID, String ELECTRONIC_FENCE_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<Boolean> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + "/deploy/fence/determineWhetherThePersonIsInTheElectronicFence2?psn=" + PLS_ID + "&id=" + ELECTRONIC_FENCE_ID, HttpMethod.GET, httpEntity, Boolean.class);
        return exchange.getBody();
    }

    public static JSONObject GetGeneralCount(String url, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(50000);
        clientHttpRequestFactory.setReadTimeout(50000);
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + url, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static String getTenantId(String CORPINFO_ID) throws Exception {
        return getBackCorpDeptId(CORPINFO_ID);
    }

    @Autowired
    public void setCorpplsinfoService(CorpPlsInfoService corpplsinfoServicebean, UsersService usersServicebean, @Qualifier("restTemplate") RestTemplate restTemplatebean) {
        corpplsinfoService = corpplsinfoServicebean;
        usersService = usersServicebean;
        restTemplate = restTemplatebean;
    }

    /**
     * @Description: 获取token
     * @Author: dearLin
     * @Date: 2024/1/24/024 9:59
     * @Param: [] []
     * @Return: java.lang.String
     */
    public static String getToken(String CORPINFO_ID) throws Exception {
        PageData pd = new PageData();
        pd.put("CORPINFO_ID", CORPINFO_ID);
        pd = corpplsinfoService.findById(pd);
        String token = pd.getString("TOKEN");
        String expireTime = pd.getString("EXPIRE_TIME");
        String userName = pd.getString("ACCOUNT");
        String passWord = pd.getString("PASSWORD");
        String enterpriseCode = pd.getString("ENTERPRISE_CODE");
        String loginUrl = pd.getString("POST_URL") + "/auth/login";
        if (token == null || expireTime == null || expireTime.trim().isEmpty() || DateUtil.compareDate(DateUtil.getTime(), expireTime)) {
            JSONObject loginPayload = new JSONObject();
            loginPayload.put("username", userName);
            loginPayload.put("password", passWord);
            loginPayload.put("enterpriseCode", enterpriseCode);
            PageData response = sendPostHttpRequest(loginUrl, loginPayload.toJSONString(), null);
            if (response != null) {
                PageData valueData = JSONObject.parseObject(response.getString("data"), PageData.class);
                JSONArray deptList = (JSONArray) valueData.get("dept_scope");
                if (deptList != null && deptList.size() > 0) {
                    PageData deptData = JSONObject.parseObject(deptList.get(0).toString(), PageData.class);
                    String deptId = deptData.getString("deptId");
                    pd.put("DEPT_ID", deptId);
                }

                token = valueData.getString("access_token");
                String newExpireTime = DateUtil.getAfterHourDate("24");
                pd.put("TOKEN", token);
                pd.put("EXPIRE_TIME", newExpireTime);
                corpplsinfoService.edit(pd);
                return token;
            } else {
                System.out.println("登录失败");
            }
        }
        return token;
    }

    /**
     * @Description: 当前在线人员实时位置信息
     * @Date: 2024/1/25/025 14:37
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject getRealTimeList(String CORPINFO_ID, String deptId) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(5000);
        clientHttpRequestFactory.setReadTimeout(5000);

        String path = getBakeAddr(CORPINFO_ID) + "/deploy/netty/coordinateDataIsPushedWhenConnected?id=" + deptId;
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(path, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();

    }

    /**
     * @Description: 电子围栏列表
     * @Author: dearLin
     * @Date: 2024/1/25/025 14:37
     * @Param: [java.lang.String, java.lang.Integer, java.lang.Integer] [keywords, currentPage, showCount]
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject getRyRegionList(String CORPINFO_ID, String keywords, Integer currentPage, Integer showCount, Integer type) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        String url = "/deploy/region/list?pageNum=" + currentPage + "&pageSize=" + showCount + "&type=" + type + "&mc=";
        if (Tools.notEmpty(keywords)) url += keywords;

        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + url, HttpMethod.GET, httpEntity, JSONObject.class);
        JSONObject data = exchange.getBody();
        if (data != null) {
            JSONArray rows = data.getJSONArray("rows");
            for (int i = 0; i < rows.size(); i++) {
                JSONObject jsonObject = rows.getJSONObject(i);
                jsonObject.put("regName", jsonObject.getString("mc"));
                jsonObject.put("layId", jsonObject.getString("layerId"));
                jsonObject.put("layName", jsonObject.getString("layerName"));
            }
            data.put("rows", rows);
        }

        return data;
    }

    public static JSONObject getRyRegionLayerInfo(String CORPINFO_ID, int id) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + "/deploy/layer/" + id, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    /**
     * @Description: 图层列表
     * @Author: dearLin
     * @Date: 2024/1/25/025 14:37
     * @Param: [java.lang.String, java.lang.Integer, java.lang.Integer] [keywords, currentPage, showCount]
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject getLayerList(String CORPINFO_ID, Integer currentPage, Integer showCount, String keywords) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        String url = "/deploy/layer/list?pageNum=" + currentPage + "&pageSize=" + showCount + "&layName=";
        if (Tools.notEmpty(keywords)) {
            url = url + keywords;
        }
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + url, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    /**
     * @Description: 获取拥有历史轨迹的全部角色
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject getPersonnelTrajectories(String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();

        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + "/deploy/personnel/allRyJbxx", HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    /**
     * @Description: 人员历史轨迹查询
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject characterTrajectories(String CORPINFO_ID, int id, String startTime, String endTime, int type) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        String url = "/deploy/personnel/anyRyHistory?id=" + id + "&startTime=" + startTime + "&endTime=" + endTime + "&type=" + type;
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);

        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + url, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }


    /**
     * @Description: 查询摄像头
     * @Author: dearLin
     * @Date: 2024/1/25/025 14:37
     * @Param: [java.lang.String, java.lang.Integer, java.lang.Integer] [keywords, currentPage, showCount]
     * @Return: com.alibaba.fastjson.JSONObject
     */
    public static JSONObject getCameraList(String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + "/deploy/camera/list?pageNum=1&pageSize=100000&str=", HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    /**
     * 发送get类型请求
     *
     * @param url
     * @param queryParams
     * @param token
     * @return PageData
     * @throws IOException
     */

    private static PageData sendGetHttpRequest(String url, Map<String, String> queryParams, String token) throws IOException {
        OkHttpClient client = new OkHttpClient();

        HttpUrl.Builder httpBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
        //封装请求参数
        if (queryParams != null) {
            for (Map.Entry<String, String> param : queryParams.entrySet()) {
                httpBuilder.addQueryParameter(param.getKey(), param.getValue());
            }
        }
        //设置请求的url
        Request.Builder requestBuilder = new Request.Builder().url(httpBuilder.build());

        if (token != null && !token.isEmpty()) {
            requestBuilder.addHeader("Authorization", "Bearer " + token);
        }

        Request request = requestBuilder.build();
        Response execute = client.newCall(request).execute();
        if (execute.code() != 200) {
            logger.error("get请求失败，返回状态码：{},url:{}", execute.code(), url);
            throw new RuntimeException("get请求失败");
        }
        return JSONObject.parseObject(execute.body().string(), PageData.class);
        //发送请求并返回响应数据
    }


    /**
     * 发送post类型请求
     *
     * @param url
     * @param jsonPayload
     * @param token
     * @return
     * @throws IOException
     */
    private static PageData sendPostHttpRequest(String url, String jsonPayload, String token) throws IOException {
        OkHttpClient client = new OkHttpClient();
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, jsonPayload);
        Request.Builder builder = new Request.Builder() // 构建一个新的Request对象。
                .url(url)// 设置请求的URL。
                .post(body);// 设置请求的方法为POST，并设置请求体。
        //构建请求头
        if (token != null && !token.isEmpty()) {// 检查token是否存在且不为空。
            builder.addHeader("Authorization", "Bearer " + token);
        }

        // 构建请求
        Request request = builder.build();
        Response execute = client.newCall(request).execute();
        if (execute.code() != 200) {
            logger.error("post请求失败，返回状态码：{},url:{}", execute.code(), url);
            throw new RuntimeException("get请求失败");
        }
        PageData pageData = JSONObject.parseObject(execute.body().string(), PageData.class);
        if (!"200".equals(pageData.getString("code"))) {
            logger.error("post请求失败，返回值：{},url:{}", pageData.getString("msg"), url);
        }
        return pageData;
        //发起请求并响应数据
    }

    /**
     * 发送PUT类型请求
     *
     * @param url
     * @param jsonPayload
     * @param token
     * @return
     * @throws IOException
     */
    private static Response sendPutHttpRequest(String url, String jsonPayload, String token) throws IOException {
        OkHttpClient client = new OkHttpClient();
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, jsonPayload);
        Request.Builder builder = new Request.Builder().url(url).put(body);
        if (token != null && !token.isEmpty()) {
            builder.addHeader("Authorization", "Bearer " + token);
        }
        Request request = builder.build();

        return client.newCall(request).execute();
    }

    /**
     * 发送delete类型请求
     *
     * @param url
     * @param camIds
     * @param token
     * @return
     * @throws IOException
     */
    private static PageData sendDeleteHttpRequest(String url, Long camIds, String token) throws IOException {
        OkHttpClient client = new OkHttpClient();
        //将要删除的Id列表转换为逗号分隔的字符串
        //构建完整的url
        url = url + "/" + camIds;

        Request.Builder builderBuilder = new Request.Builder().url(url).delete();

        if (token != null && !token.isEmpty()) {
            builderBuilder.addHeader("Authorization", "Bearer " + token);
        }

        Request request = builderBuilder.build();
        Response execute = client.newCall(request).execute();
        if (execute.code() != 200) {
            logger.error("post请求失败，返回状态码：{},url:{}", execute.code(), url);
            throw new RuntimeException("get请求失败");
        }
        PageData pageData = JSONObject.parseObject(execute.body().string(), PageData.class);
        if (!"200".equals(pageData.getString("code"))) {
            logger.error("post请求失败，返回值：{},url:{}", pageData.getString("msg"), url);
        }
        return pageData;
    }

    private static void initBakeAddr() {
        List<PageData> dataList = null;
        try {
            dataList = corpplsinfoService.listAll(new PageData());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        dataList.forEach(item -> {
            BAKEADDR.put(item.getString("CORPINFO_ID"), item.getString("POST_URL"));
            BAKEADDR.put(item.getString("CORPINFO_ID")+"tenantId", item.getString("DEPT_ID"));
        });
    }
    private static String getBackCorpDeptId(String CORPINFO_ID) throws Exception {
        return BAKEADDR.computeIfAbsent(CORPINFO_ID+"tenantId", key -> {
            initBakeAddr();
            return BAKEADDR.get(CORPINFO_ID+"tenantId");
        });
    }
    private static String getBakeAddr(String CORPINFO_ID) throws Exception {
        return BAKEADDR.computeIfAbsent(CORPINFO_ID, key -> {
            initBakeAddr();
            return BAKEADDR.get(CORPINFO_ID);
        });
    }

    public static JSONObject GeneralPost(String Url, JSONObject uriVariables, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(uriVariables, headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + Url, HttpMethod.POST, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static JSONObject GeneralPut(String Url, JSONObject uriVariables, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(uriVariables, headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + Url, HttpMethod.PUT, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static JSONObject GeneralDel(String Url, String CORPINFO_ID) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(getBakeAddr(CORPINFO_ID) + Url, HttpMethod.DELETE, httpEntity, JSONObject.class);
        return exchange.getBody();
    }
}
