package com.zcloud.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zcloud.entity.PageData;
import com.zcloud.service.bus.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.Map;

@Component
public class PLSUtil {
    private static final Logger logger = LoggerFactory.getLogger(PLSUtil.class);
    private static CorpPlsInfoService corpplsinfoService;
    private static UsersService usersService;
    private static RestTemplate restTemplate;

    @Autowired
    public void setCorpplsinfoService(CorpPlsInfoService corpplsinfoServicebean, UsersService usersServicebean, @Qualifier("restTemplate") RestTemplate restTemplatebean) {
        corpplsinfoService = corpplsinfoServicebean;
        usersService = usersServicebean;
        restTemplate = restTemplatebean;
    }
    public static JSONObject GeneralList(String Url, PageData pageData,String token) throws Exception {
        String params = buildGetParams(JSONObject.parseObject(JSON.toJSONString(pageData)));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", token);
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(Url + params, HttpMethod.GET, httpEntity, JSONObject.class);
        return exchange.getBody();
    }
    public static JSONObject GeneralPost(String url, String endpoints, PageData pageData, String CORPINFO_ID) throws Exception {
        JSONObject uriVariables = JSONObject.parseObject(JSON.toJSONString(pageData));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getToken(CORPINFO_ID));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(uriVariables, headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url + endpoints, HttpMethod.POST, httpEntity, JSONObject.class);
        return exchange.getBody();
    }
    public static JSONObject GeneralPostNotInPls(String url, PageData pageData,PageData corpPls) throws Exception {
        JSONObject uriVariables = JSONObject.parseObject(JSON.toJSONString(pageData));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", getTokenNotInPlsTable(corpPls));
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(uriVariables, headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url , HttpMethod.POST, httpEntity, JSONObject.class);
        return exchange.getBody();
    }
    public static JSONObject GeneralDelete(String url, String endpoints, 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(url + endpoints + id, HttpMethod.DELETE, httpEntity, JSONObject.class);
        return exchange.getBody();
    }

    public static String getTokenNotInPlsTable(PageData corpPls) throws Exception {
        String userName = corpPls.getString("ACCOUNT");
        String passWord = corpPls.getString("PASSWORD");
        String enterpriseCode = corpPls.getString("ENTERPRISE_CODE");
        String loginUrl = corpPls.getString("POST_URL") + "/auth/login";
        JSONObject loginPayload = new JSONObject();
        loginPayload.put("username", userName);
        loginPayload.put("password", passWord);
        loginPayload.put("enterpriseCode", enterpriseCode);
        loginPayload.put("isPresentationMode", "2");
        PageData response = sendPostHttpRequest(loginUrl, loginPayload.toJSONString(), null);
        PageData valueData = JSONObject.parseObject(response.getString("data"), PageData.class);
        return valueData.getString("access_token");
    }


    /**
     * @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 backAddr = pd.getString("POST_URL");
        String expireTime = pd.getString("EXPIRE_TIME");
        String userName = pd.getString("ACCOUNT");
        String passWord = pd.getString("PASSWORD");
        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("isPresentationMode", "2");
            PageData response = sendPostHttpRequest(loginUrl, loginPayload.toJSONString(), null);
            if (response != null) {
                PageData valueData = JSONObject.parseObject(response.getString("data"), PageData.class);
                token = valueData.getString("access_token");
                String newExpireTime = DateUtil.getAfterHourDate("24");
                pd.put("TOKEN", token);
                pd.put("EXPIRE_TIME", newExpireTime);
                corpplsinfoService.editToken(pd);
                return token;
            } else {
                System.out.println("登录失败");
            }
        }
        return token;
    }

    public static JSONObject GetGeneralCount(String url, String corpinfoId) {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(headers);
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(5000);
        clientHttpRequestFactory.setReadTimeout(5000);
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class);

        return exchange.getBody();
    }

    public static boolean testUrl(String loginUrl, String userName, String passWord, String CORPINFO_ID) {
        JSONObject loginPayload = new JSONObject();
        loginPayload.put("username", userName);
        loginPayload.put("password", passWord);
        loginPayload.put("isPresentationMode", "2");
        try {
            PageData response = sendPostHttpRequest(loginUrl, loginPayload.toJSONString(), null);
            PageData pageData = new PageData();
            PageData valueData = JSONObject.parseObject(response.getString("data"), PageData.class);
            String token = valueData.getString("access_token");
            String newExpireTime = DateUtil.getAfterHourDate("24");
            pageData.put("TOKEN", token);
            pageData.put("CORPINFO_ID", CORPINFO_ID);
            pageData.put("EXPIRE_TIME", newExpireTime);
            corpplsinfoService.editToken(pageData);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 发送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;
    }

    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();
    }

}
