package com.dgtly.system.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: csz
 * @Date: 2020/7/15 16:39
 * @Modified: 2026/05/09 使用Spring RestTemplate替代OkHttp，解决NoClassDefFoundError问题
 */
public class HttpUtil {

    private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);
    private static RestTemplate restTemplate;

    static {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(30000);  // 连接超时30秒
        factory.setReadTimeout(30000);     // 读取超时30秒
        restTemplate = new RestTemplate(factory);
    }

    public static String executePostBodyJsonParamList(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
        List<Map<String, String>> maps = Arrays.asList(params);
        return executePostBodyJsonParam(url, headers, maps);
    }

    public static <T> String executePostBodyJsonParam(String url, Map<String, String> headers, T params) throws Exception {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }
        }
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        String jsonBody = JSON.toJSONString(params, SerializerFeature.WriteMapNullValue);
        HttpEntity<String> entity = new HttpEntity<>(jsonBody, httpHeaders);

        log.info("ESB请求 url = [{}], headers = [{}], params = [{}]", url, JSON.toJSONString(headers), jsonBody);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        String body = response.getBody();
        log.info("ESB响应 returnString = [{}]", body);
        return body;
    }

    public static <T> String executePostBodyJsonParamRetry(String url, Map<String, String> headers, T params) throws Exception {
        // 简单重试逻辑：重试3次
        int maxRetries = 3;
        Exception lastException = null;
        
        for (int i = 0; i < maxRetries; i++) {
            try {
                log.info("ESB重发次数 headers = [{}], params = [{}], count = [{}]", headers, params, i + 1);
                return executePostBodyJsonParam(url, headers, params);
            } catch (Exception e) {
                lastException = e;
                log.warn("ESB请求失败，第{}次重试", i + 1, e);
                if (i < maxRetries - 1) {
                    Thread.sleep(1000); // 重试间隔1秒
                }
            }
        }
        throw new Exception("ESB请求失败，已重试" + maxRetries + "次", lastException);
    }

    public static String executePostFormParam(String url, Map<String, String> headers, Map<String, String> params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }
        }
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 构建form参数
        String formBody = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        HttpEntity<String> entity = new HttpEntity<>(formBody, httpHeaders);

        String returnString = null;
        try {
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            returnString = response.getBody();
            log.info("onResponse is {}", returnString);
        } catch (Exception e) {
            log.error("[{}] request error , heads is [{}], params is [{}]", url, JSON.toJSONString(headers), JSON.toJSONString(params), e);
        }
        return returnString;
    }


    public static String executePostJsonParam(String url, Map<String, String> headers, Map<String, String> params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }
        }
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        String paramJson = JSON.toJSONString(params, SerializerFeature.WriteMapNullValue);
        HttpEntity<String> entity = new HttpEntity<>(paramJson, httpHeaders);

        String returnString = null;
        try {
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            returnString = response.getBody();
            log.info("onResponse is {}", returnString);
        } catch (Exception e) {
            log.error("[{}] request error , heads is [{}], params is [{}]", url, JSON.toJSONString(headers), JSON.toJSONString(params), e);
        }
        return returnString;
    }

    /**
     * @description: get方法
     * @param: [url, headers, params]
     * @return: java.lang.String
     * @author: njs     
     * @date: 2025/6/17 13:26
     */
    public static String executeGet(String url, Map<String, String> headers, Map<String, String> params) {
        // 拼接GET参数
        if (params != null && params.size() > 0) {
            List<String> noticeParams = params.entrySet().stream()
                    .map(entry -> entry.getKey() + "=" + entry.getValue())
                    .collect(Collectors.toList());
            url = url + "?" + StringUtils.join(noticeParams, "&");
        }
        log.info("url is [{}]", url);

        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }
        }

        HttpEntity<String> entity = new HttpEntity<>("", httpHeaders);

        String returnString = null;
        try {
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
            returnString = response.getBody();
            log.info("onResponse is {}", returnString);
        } catch (Exception e) {
            log.warn("request is error, url =[{}]", url, e);
        }
        return returnString;
    }
}
