package com.ruoyi.common.utils.rest;


import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class RestUtil {
    @Autowired
    private RestTemplate restTemplate;

    //一些自定义的请求头参数
    public static final String supplierID = "";
    public static final String interfacekey = "";


    /**
     * DLT专用执行方法
     *
     * @param param  请求参数：可以添加一些常量请求值
     * @param url    访问的url
     * @param method 请求的方法
     * @return
     */
    public String execute(Map<String, Object> param, String url, HttpMethod method) {
        HttpHeaders headers = this.getDefaultHeader();
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }


    /**
     * DLT专用执行方法
     *
     * @param url    访问的url
     * @param method 请求的方法
     * @return
     */
    public String execute(String url, HttpMethod method) {
        Map<String, Object> param = new HashMap<>();
        HttpHeaders headers = this.getDefaultHeader();
        Map<String, Object> requestor = this.getDefaultParam();
        param.put("requestor" , requestor);
        param.put("supplierID" , supplierID);
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }


    /**
     * DLT专用执行方法
     *
     * @param param  请求参数：可以添加一些常量请求值
     * @param url    访问的url
     * @param method 请求的方法
     * @return
     */
    public String execute(Map<String, Object> headerMap, Map<String, Object> param, String url, HttpMethod method) {
        HttpHeaders headers = new HttpHeaders();
        headerMap.entrySet().forEach(o -> {
            headers.add(o.getKey(), o.getValue().toString());
        });
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }


    /**
     * get请求
     *
     * @param url      请求的url
     * @param jsonData 请求的json
     * @return
     */
    public String restGet(String url, String jsonData) {

        return request(url, jsonData, HttpMethod.GET);

    }


    /**
     * @param url        请求的url
     * @param jsonData   json数据
     * @param httpMethod
     * @return
     */
    private String request(String url, String jsonData, HttpMethod httpMethod) {

        ResponseEntity<String> response = null;

        try {
            if (StringUtils.isEmpty(url)) {

                throw new IllegalArgumentException();
            }

            HttpEntity<String> requestEntity = new HttpEntity<String>(jsonData);
            response = restTemplate.exchange(url, httpMethod, requestEntity, String.class);

        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
        return response.getBody().toString();
    }

    /**
     * Get请求获取实体类
     *
     * @param url          请求的url
     * @param responseType 返回的类型
     * @param requestMap   请求参数
     * @param <T>          泛型
     * @return
     */
    public <T> T getForEntity(String url, Class<T> responseType, Map<String, Object> requestMap) {
        return (T) exchangePackaging(url, HttpMethod.GET, responseType, requestMap, null, null);
    }

    /**
     * 设置请求头
     */
    public <T> T getForEntitySetHeaders(String url, Class<T> responseType, Map<String, Object> requestMap, HttpHeaders headers) {
        return (T) exchangePackaging(url, HttpMethod.GET, responseType, requestMap, null, headers);
    }

    /**
     * Post请求获取实体类
     *
     * @param url          请求的url
     * @param responseType 返回的类型
     * @param requestMap   请求参数
     * @param body         body参数
     * @param <T>          泛型
     * @return
     */
    public <T> T postForEntity(String url, Class<T> responseType, Map<String, Object> requestMap, Object body) {
        return (T) exchangePackaging(url, HttpMethod.POST, responseType, requestMap, body, null);
    }

    /**
     * 设置请求头
     */
    public <T> T postForEntitySetHeaders(String url, Class<T> responseType, Map<String, Object> requestMap, Object body, HttpHeaders headers) {
        return (T) exchangePackaging(url, HttpMethod.POST, responseType, requestMap, body, headers);
    }

    /**
     * Put请求获取实体类
     *
     * @param url          请求的url
     * @param responseType 返回的类型
     * @param requestMap   请求参数
     * @param body         body参数
     * @param <T>          泛型
     * @return
     */
    public <T> T putForEntity(String url, Class<T> responseType, Map<String, Object> requestMap, Object body) {
        return (T) exchangePackaging(url, HttpMethod.PUT, responseType, requestMap, body, null);
    }

    /**
     * 设置请求头
     */
    public <T> T putForEntitySetHeaders(String url, Class<T> responseType, Map<String, Object> requestMap, Object body, HttpHeaders headers) {
        return (T) exchangePackaging(url, HttpMethod.PUT, responseType, requestMap, body, headers);
    }

    /**
     * DELETE请求获取实体类
     *
     * @param url          请求的url
     * @param responseType 返回的类型
     * @param requestMap   请求参数
     * @param body         body参数
     * @param <T>          泛型
     * @return
     */
    public <T> T deleteForEntity(String url, Class<T> responseType, Map<String, Object> requestMap, Object body) {
        return (T) exchangePackaging(url, HttpMethod.DELETE, responseType, requestMap, body, null);
    }

    /**
     * 设置请求头
     */
    public <T> T deleteForEntitySetHeaders(String url, Class<T> responseType, Map<String, Object> requestMap, Object body, HttpHeaders headers) {
        return (T) exchangePackaging(url, HttpMethod.DELETE, responseType, requestMap, body, headers);
    }

    /**
     * 获得数据
     *
     * @param url          请求的url
     * @param method       请求的方式
     * @param responseType 返回的类型
     * @param requestMap   请求参数
     * @param body         body参数
     * @param <T>          泛型
     * @return
     */
    public <T> T exchangePackaging(String url, HttpMethod method, Class<T> responseType,
                                   Map<String, Object> requestMap, Object body, HttpHeaders headers) {

        //处理请求参数
        StringBuffer stringBuffer = new StringBuffer(url);

        if (requestMap != null) {
            Iterator iterator = requestMap.entrySet().iterator();
            if (iterator.hasNext()) {
                stringBuffer.append("?");
                Object element;
                while (iterator.hasNext()) {
                    element = iterator.next();
                    Map.Entry<String, Object> entry = (Map.Entry) element;
                    //过滤value为null，value为null时进行拼接字符串会变成 "null"字符串
                    if (entry.getValue() != null) {
                        stringBuffer.append(element).append("&");
                    }
                    url = stringBuffer.substring(0, stringBuffer.length() - 1);
                }
            }
        }

        System.out.println("url请求：" + url);

        // 1，设置请求头
        if (ObjectUtil.isNull(headers)) {
            headers = new HttpHeaders();
        }

        //请求体的MIME类型 （用于POST和PUT请求中）
        if (ObjectUtil.isNull(headers.getContentType())) {
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        }

        // 2. 封装请求头和 参数
        HttpEntity<Object> httpEntity = new HttpEntity<>(body, headers);

        // 3,发送请求，指定请求方式
        // 使用exchange请求接口
        ResponseEntity<T> exchange = restTemplate.exchange(url, method, httpEntity, responseType);
        System.out.println("result结果：" + exchange.getBody());

        return exchange.getBody();
    }


    /**
     * 获取默认的头请求信息
     *
     * @return
     */
    public HttpHeaders getDefaultHeader() {
        String timestamp = "" + System.currentTimeMillis();
        String signature = EncoderByMd5(supplierID + timestamp + interfacekey);
        HttpHeaders headers = new HttpHeaders();
        headers.add("signature" , signature);
        headers.add("timestamp" , timestamp);
        return headers;
    }


    /**
     * 获取默认的参数
     *
     * @return
     */
    public Map<String, Object> getDefaultParam() {
        Map<String, Object> defParam = new HashMap<>();
        defParam.put("invoker" , "xx");
        defParam.put("operatorName" , "xx");
        return defParam;
    }


    /**
     * 通过MD5加密
     *
     * @param str
     * @return
     */
    public static String EncoderByMd5(String str) {
        if (str == null) {
            return null;
        }
        try {
            // 确定计算方法
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            BASE64Encoder base64en = new BASE64Encoder();
            // 加密后的字符串
            return base64en.encode(md5.digest(str.getBytes("utf-8"))).toUpperCase();
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            return null;
        }
    }
}
