package com.yn.bftl.thirdparty.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yn.bftl.common.common.exception.YnceError;
import com.yn.bftl.thirdparty.common.exception.YnceErrorException;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Iterator;
import java.util.Map;

/**
 * http对应请求
 * 之前编写的HttpRequestUtil局限太大，重新成HttpClientUtil
 *
 * @author chendehuihuo
 * @create 2022-02-22
 */
public class HttpClientUtil<T> {

    /**
     * 创建静态私有的变量保存该类对象
     */
    static private HttpClientUtil instance;

    static private HttpHeaders headers;

    static private RestTemplate restTemplate;

    /**
     * 工厂模式
     */
    public static HttpClientUtil getInstance() {
        //判断instance是否是Uni的对象
        //没有则创建
        if (instance == null) {
            instance = new HttpClientUtil();
        }
        if (headers == null) {
            headers = new HttpHeaders();
        } else {
            headers.clear();
        }
        if (restTemplate == null) {
            // 配置restTemplate
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
            httpRequestFactory.setConnectionRequestTimeout(3000);
            httpRequestFactory.setConnectTimeout(3000);
            httpRequestFactory.setReadTimeout(30000);
            restTemplate = new RestTemplate(httpRequestFactory);
        }
        // 默认为application/json
        headers.setContentType(MediaType.APPLICATION_JSON);
        return instance;
    }

    public HttpClientUtil setContentType(MediaType mediaType) {
        headers.setContentType(mediaType);
        return instance;
    }

    public HttpClientUtil setHeaderMap(Map<String, String> headerMap) {
        if (headerMap.size() != 0) {
            for (Map.Entry<String, String> stringStringEntry : headerMap.entrySet()) {
                headers.add(stringStringEntry.getKey(), stringStringEntry.getValue());
            }
        }
        return instance;
    }

    /**
     * restTemplate-GET请求
     *
     * @param url          请求路径
     * @param urlParamsMap URL参数集合
     * @return JSONObject
     * @author huabiao
     * @create 2023/5/30  17:20
     */
    public JSONObject sendGet(String url, Map<String, Object> urlParamsMap) {
        // 处理URL请求参数
        String requestUrl = jointUrlParams(url, urlParamsMap);
        ResponseEntity<JSONObject> resp = restTemplate.getForEntity(requestUrl, JSONObject.class);

        if (resp.getStatusCodeValue() != 200) {
            throw new YnceErrorException(YnceError.YNCE_000000);
        }
        JSONObject body = resp.getBody();
        if (body == null) {
            throw new YnceErrorException(YnceError.YNCE_100002);
        }

        return body;
    }


    /**
     * restTemplate-POST请求
     *
     * @param url         请求路径
     * @param requestJson 请求参数
     * @return JSONObject
     * @author huabiao
     * @create 2023/5/30  17:20
     */
    public JSONObject sendPost(String url, Object requestJson) {
        HttpEntity<Object> entity = new HttpEntity<>(setParam(requestJson), headers);
        ResponseEntity<JSONObject> resp = restTemplate.postForEntity(url, entity, JSONObject.class);

        if (resp.getStatusCodeValue() != 200) {
            throw new YnceErrorException(YnceError.YNCE_000000);
        }
        JSONObject body = resp.getBody();
        if (body == null) {
            throw new YnceErrorException(YnceError.YNCE_100002);
        }
        return body;
    }

    /**
     * 添加路径请求参数
     *
     * @param url          请求路径
     * @param urlParamsMap 请求路径参数集合(此参数)
     * @return 请求路径
     * @description
     * @author huabiao
     * @create 2023/5/30  17:18
     */
    private static String jointUrlParams(String url, Map<String, Object> urlParamsMap) {
        String requestUrl = url;
        if (BooleanUtils.isFalse(urlParamsMap.isEmpty())) {
            // 若RUL参数不为空则处理
            String urlParams = setUrlParams(urlParamsMap);
            if (url.contains("=")) {
                requestUrl += ("&" + urlParams);
            } else {
                requestUrl += ("?" + urlParams);
            }
        }
        return requestUrl;
    }

    /**
     * 设置URL参数
     *
     * @param params 请求参数
     * @return URL参数
     * @author huabiao
     * @create 2023/5/30  17:07
     */
    private static String setUrlParams(Map<String, Object> params) {
        Iterator<String> paramsIterator = params.keySet().iterator();
        StringBuilder paramsStringBuilder = new StringBuilder();
        while (paramsIterator.hasNext()) {
            String key = paramsIterator.next();
            if (params.get(key) == null || "".equals(params.get(key).toString())) {
                continue;
            }
            paramsStringBuilder.append("&").append(key).append("=").append(params.get(key));
        }
        // 去掉第一个&并返回
        return paramsStringBuilder.substring(1);
    }

    /**
     * 参数对象-格式化
     *
     * @param paramObject 参数对象
     * @return 对象
     * @description
     * @author huabiao
     * @create 2023/5/30  17:19
     */
    private static Object setParam(Object paramObject) {
        if (paramObject instanceof String) {
            return paramObject;
        }
        String requestJson = JSON.toJSONString(paramObject);
        if (paramObject == null || paramObject == "") {
            return JSON.toJSONString(new JSONObject());
        }

        // 如果是application/x-www-form-urlencoded请求方式就格式化数据
        if (MediaType.APPLICATION_FORM_URLENCODED.equals(headers.getContentType())) {
            return paramObject;
        }

        if (MediaType.TEXT_PLAIN.equals(headers.getContentType())) {
            return paramObject;
        }
        return requestJson;
    }
}
