package com.css.txw.common.util;

import com.css.ggzc.framework.cache.utils.XtcsUtils;
import com.css.ggzc.framework.common.util.gy.GyUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.Proxy;
import java.util.Map;

/**
 * 基于Spring Cloud Alibaba的HTTP工具类
 * 支持GET、POST、PUT、DELETE请求，兼容HTTP/HTTPS协议
 * 支持Nacos服务发现和负载均衡
 * 版本：Spring Cloud Alibaba 2021.0.6.0
 */
@Slf4j
@Component
public class TxwHttpUtils {
    
    @Resource
    private RestTemplate restTemplate = new RestTemplate();


    private final ObjectMapper objectMapper = new ObjectMapper();

    @PostConstruct
    public void init() {
        log.info("SpringCloudAlibabaHttpUtil initialized successfully with Spring Cloud Alibaba 2021.0.6.0");
    }

    // ========== GET请求方法 ==========

    /**
     * GET请求 - 直接URL调用
     */
    public <T> T get(String url, Class<T> responseType) {
        return get(url, null, responseType, null);
    }

    public <T> T get(String url, Map<String, Object> params, Class<T> responseType) {
        return get(url, params, responseType, null);
    }

    public <T> T get(String url, Map<String, Object> params, Class<T> responseType,
                     Map<String, String> headers) {
        try {
            HttpEntity<?> entity = createHttpEntity(null, headers);
            ResponseEntity<T> response = restTemplate.exchange(
                    buildUrlWithParams(url, params),
                    HttpMethod.GET,
                    entity,
                    responseType
            );
            return handleResponse(response);
        } catch (Exception e) {
            log.error("GET请求失败, url: {}", url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }

    // ========== POST请求方法 ==========

    /**
     * POST请求 - 直接URL调用
     */
    public <T> T post(String url, Object requestBody, Class<T> responseType) {
        return post(url, requestBody, responseType, null);
    }

    public <T> T post(String url, Object requestBody, Class<T> responseType,
                      Map<String, String> headers) {
        try {
            HttpEntity<?> entity = createHttpEntity(requestBody, headers);
            ResponseEntity<T> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    entity,
                    responseType
            );
            return handleResponse(response);
        } catch (Exception e) {
            log.error("POST请求失败, url: {}", url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }

    // ========== PUT请求方法 ==========

    /**
     * PUT请求 - 直接URL调用
     */
    public <T> T put(String url, Object requestBody, Class<T> responseType) {
        return put(url, requestBody, responseType, null);
    }

    public <T> T put(String url, Object requestBody, Class<T> responseType,
                     Map<String, String> headers) {
        try {
            HttpEntity<?> entity = createHttpEntity(requestBody, headers);
            ResponseEntity<T> response = restTemplate.exchange(
                    url,
                    HttpMethod.PUT,
                    entity,
                    responseType
            );
            return handleResponse(response);
        } catch (Exception e) {
            log.error("PUT请求失败, url: {}", url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }

    // ========== DELETE请求方法 ==========

    /**
     * DELETE请求 - 直接URL调用
     */
    public <T> T delete(String url, Class<T> responseType) {
        return delete(url, null, responseType, null);
    }

    public <T> T delete(String url, Map<String, Object> params, Class<T> responseType) {
        return delete(url, params, responseType, null);
    }

    public <T> T delete(String url, Map<String, Object> params, Class<T> responseType,
                        Map<String, String> headers) {
        try {
            HttpEntity<?> entity = createHttpEntity(null, headers);
            ResponseEntity<T> response = restTemplate.exchange(
                    buildUrlWithParams(url, params),
                    HttpMethod.DELETE,
                    entity,
                    responseType
            );
            return handleResponse(response);
        } catch (Exception e) {
            log.error("DELETE请求失败, url: {}", url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }

    // ========== 通用请求方法 ==========

    /**
     * 通用请求方法
     */
    public <T> T exchange(String url, HttpMethod method, Object requestBody,
                          Map<String, String> headers, Class<T> responseType) {
        try {
            ResponseEntity<T> response;
            RestTemplate restTemplateWithProxy = createRestTemplateWithProxy();
            HttpEntity<?> entity = createHttpEntity(requestBody, headers);
            if (GyUtils.isNotNull(restTemplateWithProxy)) {
                response = restTemplateWithProxy.exchange(url, method, entity, responseType);
            } else {
                response = restTemplate.exchange(url, method, entity, responseType);
            }
            return handleResponse(response);
        } catch (Exception e) {
            log.error("{}请求失败, url: {}", method.name(), url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }

    // ========== 辅助方法 ==========

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

        StringBuilder urlBuilder = new StringBuilder(url);
        boolean hasQuery = url.contains("?");

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (entry.getValue() == null) continue;

            if (!hasQuery) {
                urlBuilder.append("?");
                hasQuery = true;
            } else {
                urlBuilder.append("&");
            }

            urlBuilder.append(entry.getKey())
                    .append("=")
                    .append(encodeParam(entry.getValue().toString()));
        }

        return urlBuilder.toString();
    }

    /**
     * 参数编码
     */
    private String encodeParam(String param) {
        try {
            return java.net.URLEncoder.encode(param, "UTF-8");
        } catch (Exception e) {
            log.warn("参数编码失败: {}", param, e);
            return param;
        }
    }

    /**
     * 创建HTTP实体
     */
    private HttpEntity<?> createHttpEntity(Object requestBody, Map<String, String> headers) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置默认头
        if (requestBody instanceof MultiValueMap) {
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        } else if (requestBody != null) {
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        }

        // 添加自定义头
        if (headers != null) {
            headers.forEach(httpHeaders::add);
        }

        return new HttpEntity<>(requestBody, httpHeaders);
    }

    /**
     * 处理响应
     */
    private <T> T handleResponse(ResponseEntity<T> response) {
        if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        } else {
            String errorMsg = String.format("HTTP请求失败, 状态码: %d, 响应: %s",
                    response.getStatusCodeValue(), response.getBody());
            log.error(errorMsg);
            throw new RuntimeException(errorMsg);
        }
    }

    /**
     * 将对象转换为MultiValueMap（用于表单提交）
     */
    public MultiValueMap<String, String> convertToFormData(Object obj) {
        try {
            MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
            Map<String, Object> map = objectMapper.convertValue(obj, new TypeReference<Map<String, Object>>() {});

            map.forEach((key, value) -> {
                if (value != null) {
                    formData.add(key, value.toString());
                }
            });

            return formData;
        } catch (Exception e) {
            log.error("对象转换表单数据失败", e);
            throw new RuntimeException("对象转换失败", e);
        }
    }

    public RestTemplate createRestTemplateWithProxy() {
        // 设置代理
        Proxy proxy = XtcsUtils.getSystemHttpProxy();
        if (GyUtils.isNotNull(proxy)) {
            SimpleClientHttpRequestFactory requestFactory =
                    new SimpleClientHttpRequestFactory();
            // 设置超时时间
            requestFactory.setConnectTimeout(5000);
            requestFactory.setReadTimeout(10000);
            requestFactory.setProxy(proxy);
            return new RestTemplate(requestFactory);
        }
        return null;
    }
}