package com.njcn.msgpush.module.push.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
@Component
public class RestTemplateUtil {

    private final RestTemplate restTemplate;

    public RestTemplateUtil() {
        this.restTemplate = new RestTemplate();
    }

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

    public <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType) {
        try {
            HttpEntity<String> requestEntity = new HttpEntity<>(headers);
            log.info("发送GET请求到: {}", url);
            ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, responseType);
            log.info("GET请求响应状态: {}", response.getStatusCode());
            return response;
        } catch (Exception e) {
            log.error("GET请求异常: {}", e.getMessage(), e);
            throw e;
        }
    }

    public <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) {
        return post(url, requestBody, null, responseType);
    }

    public <T> ResponseEntity<T> post(String url, Object requestBody, HttpHeaders headers, Class<T> responseType) {
        try {
            if (headers == null) {
                headers = new HttpHeaders();
            }
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
            log.info("发送POST请求到: {}", url);
            ResponseEntity<T> response = restTemplate.postForEntity(url, entity, responseType);
            log.info("POST请求响应状态: {}", response.getStatusCode());
            return response;
        } catch (Exception e) {
            log.error("POST请求异常: {}", e.getMessage(), e);
            throw e;
        }
    }

    public <T> ResponseEntity<T> postForm(String url, Map<String, String> formData, Class<T> responseType) {
        return postForm(url, formData, null, responseType);
    }

    public <T> ResponseEntity<T> postForm(String url, Map<String, String> formData, HttpHeaders headers, Class<T> responseType) {
        try {
            if (headers == null) {
                headers = new HttpHeaders();
            }
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<Map<String, String>> entity = new HttpEntity<>(formData, headers);
            log.info("发送POST表单请求到: {}", url);
            ResponseEntity<T> response = restTemplate.postForEntity(url, entity, responseType);
            log.info("POST表单请求响应状态: {}", response.getStatusCode());
            return response;
        } catch (Exception e) {
            log.error("POST表单请求异常: {}", e.getMessage(), e);
            throw e;
        }
    }

    public <T> T getForObject(String url, Class<T> responseType) {
        try {
            log.info("发送GET请求获取对象到: {}", url);
            T result = restTemplate.getForObject(url, responseType);
            log.info("GET请求成功获取对象");
            return result;
        } catch (Exception e) {
            log.error("GET请求获取对象异常: {}", e.getMessage(), e);
            throw e;
        }
    }

    public <T> T postForObject(String url, Object requestBody, Class<T> responseType) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);

            log.info("发送POST请求获取对象到: {}", url);
            T result = restTemplate.postForObject(url, entity, responseType);
            log.info("POST请求成功获取对象");
            return result;
        } catch (Exception e) {
            log.error("POST请求获取对象异常: {}", e.getMessage(), e);
            throw e;
        }
    }

    public String getString(String url) {
        return getForObject(url, String.class);
    }

    public String postString(String url, Object requestBody) {
        return postForObject(url, requestBody, String.class);
    }
}