package cn.iocoder.yudao.module.system.controller.admin.myUtils;

import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
 * HTTP请求工具类
 * 支持HTTP/HTTPS协议自动判断
 * 支持GET/POST/PUT/DELETE请求方法
 */
public class MyHttpUtils {

    private static RestTemplate restTemplate;

    static {
        // 初始化RestTemplate，支持HTTPS
        restTemplate = createRestTemplate();
    }

    /**
     * 创建支持HTTPS的RestTemplate
     */
    private static RestTemplate createRestTemplate() {
        try {
            // 信任所有证书
            TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
            SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                    .loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();

            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(csf)
                    .build();

            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            requestFactory.setHttpClient(httpClient);

            // 设置连接和读取超时时间（单位：毫秒）
            requestFactory.setConnectTimeout(5000);
            requestFactory.setReadTimeout(10000);

            return new RestTemplate(requestFactory);
        } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {
            throw new RuntimeException("创建RestTemplate失败", e);
        }
    }

    /**
     * 发送GET请求
     * @param url 请求地址
     * @param headers 请求头
     * @param params 请求参数
     * @return 响应结果
     */
    public static String get(String url, Map<String, String> headers, Map<String, Object> params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);

        // 处理URL参数
        String fullUrl = buildUrlWithParams(url, params);

        ResponseEntity<String> response = restTemplate.exchange(
                fullUrl, HttpMethod.GET, requestEntity, String.class);
        return response.getBody();
    }

    /**
     * 发送POST请求（JSON格式）
     * @param url 请求地址
     * @param headers 请求头
     * @param body 请求体（JSON字符串）
     * @return 响应结果
     */
    public static String postJson(String url, Map<String, String> headers, String body) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        HttpEntity<String> requestEntity = new HttpEntity<>(body, httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.POST, requestEntity, String.class);
        return response.getBody();
    }

    /**
     * 发送POST请求（表单格式）
     * @param url 请求地址
     * @param headers 请求头
     * @param formData 表单数据
     * @return 响应结果
     */
    public static String postForm(String url, Map<String, String> headers, Map<String, String> formData) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        if (formData != null) {
            formData.forEach(map::add);
        }

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(map, httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.POST, requestEntity, String.class);
        return response.getBody();
    }

    /**
     * 发送PUT请求（JSON格式）
     * @param url 请求地址
     * @param headers 请求头
     * @param body 请求体（JSON字符串）
     * @return 响应结果
     */
    public static String putJson(String url, Map<String, String> headers, String body) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        HttpEntity<String> requestEntity = new HttpEntity<>(body, httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.PUT, requestEntity, String.class);
        return response.getBody();
    }

    /**
     * 发送DELETE请求
     * @param url 请求地址
     * @param headers 请求头
     * @param params 请求参数
     * @return 响应结果
     */
    public static String delete(String url, Map<String, String> headers, Map<String, Object> params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders);

        // 处理URL参数
        String fullUrl = buildUrlWithParams(url, params);

        ResponseEntity<String> response = restTemplate.exchange(
                fullUrl, HttpMethod.DELETE, requestEntity, String.class);
        return response.getBody();
    }

    /**
     * 构建带参数的URL
     * @param url 原始URL
     * @param params 参数Map
     * @return 带参数的URL
     */
    private static String buildUrlWithParams(String url, Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            return url;
        }

        StringBuilder sb = new StringBuilder(url);
        if (!url.contains("?")) {
            sb.append("?");
        } else {
            sb.append("&");
        }

        params.forEach((key, value) -> sb.append(key).append("=").append(value).append("&"));

        // 删除最后一个多余的&
        return sb.substring(0, sb.length() - 1);
    }
}
