package com.zsElectric.boot.common.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class OkHttpUtil {
    private final OkHttpClient okHttpClient;
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public OkHttpUtil(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    /**
     * 执行 GET 请求，返回 JsonNode
     */
    public JsonNode doGet(String url, Map<String, String> headers) throws IOException {
        Request.Builder requestBuilder = new Request.Builder().url(url);

        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }

        Request request = requestBuilder.build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response);
            }
            String responseBody = response.body().string();
            return objectMapper.readTree(responseBody);
        }
    }

    /**
     * 执行 POST 请求（JSON 数据），返回 JsonNode
     */
    public JsonNode doPostJson(String url, String json, Map<String, String> headers) throws IOException {
        RequestBody body = RequestBody.create(json, JSON);

        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .post(body);

        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }

        Request request = requestBuilder.build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response);
            }
            String responseBody = response.body().string();
            return objectMapper.readTree(responseBody);
        }
    }

    /**
     * 执行 POST 请求（表单数据），返回 JsonNode
     */
    public JsonNode doPostForm(String url, String json, Map<String, String> headers) {
        try {
            RequestBody body = RequestBody.create(json, JSON);

            Request.Builder requestBuilder = new Request.Builder()
                    .url(url)
                    .post(body);

            // 设置 headers
            if (MapUtil.isNotEmpty(headers)) {
                headers.forEach(requestBuilder::addHeader);
            }
            requestBuilder.addHeader("Content-Type", "application/json;charset=utf-8");

            Request request = requestBuilder.build();
            log.info("POST 请求 URL: " + url);
            log.info("POST 请求 JSON 数据: " + json);
            Response response = okHttpClient.newCall(request).execute();
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "";
                log.error("HTTP 请求失败，URL: {}, 状态码: {}, 响应: {}", url, response.code(), errorBody);
                throw new IOException("请求失败，状态码: " + response.code() + ", 响应: " + errorBody);
            }
            String responseBody = response.body().string();
            log.info("HTTP 请求成功，URL: {}, 响应: {}", url, responseBody);
            response.close();
            return objectMapper.readTree(responseBody);
        } catch (IOException e) {
            log.error("HTTP 请求异常，URL: {}", url, e);
            throw new RuntimeException("请求异常: " + e.getMessage(), e);
        }
    }

    public JsonNode doPostForm(String url, Map<String, Object> formData, Map<String, String> headers) {
        try {
            FormBody.Builder formBodyBuilder = new FormBody.Builder();
            if (formData != null) {
                formData.forEach((k, v) -> formBodyBuilder.add(k, String.valueOf(v)));
            }

            Request.Builder requestBuilder = new Request.Builder()
                    .url(url)
                    .post(formBodyBuilder.build());

            // 正确设置 Content-Type header
            if (MapUtil.isNotEmpty(headers)) {
                headers.forEach(requestBuilder::addHeader);
            }

            Request request = requestBuilder.build();
            log.info("POST 请求 URL: " + url);
            log.info("POST 请求表单数据: " + formData);
            Response response = okHttpClient.newCall(request).execute();
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "";
                log.error("HTTP 请求失败，URL: {}, 状态码: {}, 响应: {}", url, response.code(), errorBody);
                throw new IOException("请求失败，状态码: " + response.code() + ", 响应: " + errorBody);
            }
            String responseBody = response.body().string();
            log.info("HTTP 请求成功，URL: {}, 响应: {}", url, responseBody);
            response.close();
            return objectMapper.readTree(responseBody);
        } catch (IOException e) {
            log.error("HTTP 请求异常，URL: {}", url, e);
            throw new RuntimeException("请求异常: " + e.getMessage(), e);
        }
    }

    /**
     * 异步 GET 请求
     */
    public void doGetAsync(String url, Map<String, String> headers, Callback callback) {
        Request.Builder requestBuilder = new Request.Builder().url(url);

        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }

        Request request = requestBuilder.build();
        okHttpClient.newCall(request).enqueue(callback);
    }

    /**
     * 执行 GET 请求，返回字符串（保留原有方法）
     */
    public String doGetAsString(String url, Map<String, String> headers) throws IOException {
        Request.Builder requestBuilder = new Request.Builder().url(url);

        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }

        requestBuilder.addHeader("Content-Type", "application/json");

        Request request = requestBuilder.build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response);
            }
            return response.body().string();
        }
    }
}