package com.cool.store.utils;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;

/**
 * @Author suzhuhong
 * @Date 2025/10/10 14:21
 * @Version 1.0
 * OkHttp工具类
 */
@Slf4j
@Component
public class OkHttpUtil {

    @Autowired
    private OkHttpClient okHttpClient;

    @Autowired
    private ObjectMapper objectMapper;

    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    /**
     * GET请求
     */
    public String doGet(String url) throws IOException {
        return doGet(url, null);
    }

    /**
     * GET请求 - 带请求头
     */
    public String doGet(String url, Map<String, String> headers) throws IOException {
        Request.Builder builder = new Request.Builder().url(url);

        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }

        Request request = builder.build();

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

    /**
     * POST请求 - JSON数据
     */
    public String doPostJson(String url, Object data) throws IOException {
        return doPostJson(url, data, null);
    }

    /**
     * POST请求 - JSON数据，带请求头
     */
    public String doPostJson(String url, Object data, Map<String, String> headers) throws IOException {
        //打印日志
        logRequest(url, data);

        String json = objectMapper.writeValueAsString(data);
        RequestBody requestBody = RequestBody.create( JSON,json);
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);

        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }

        Request request = builder.build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new ServiceException(ErrorCodeEnum.THIRD_API_ERROR,
                        "HTTP请求失败，状态码: " + response.code());
            }
            ResponseBody body = response.body();

            String responseBody = body != null ? body.string() : null;

            logResponse(url, response.code(), responseBody);
            return responseBody;
        }
    }

    /**
     * 异步GET请求
     */
    public void doGetAsync(String url, Callback callback) {
        doGetAsync(url, null, callback);
    }

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

        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }

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

    /**
     * 异步POST请求
     */
    public void doPostAsync(String url, Object data, Callback callback) {
        doPostAsync(url, data, null, callback);
    }

    /**
     * 异步POST请求 - 带请求头
     */
    public void doPostAsync(String url, Object data, Map<String, String> headers, Callback callback) {
        try {
            String json = objectMapper.writeValueAsString(data);
            RequestBody requestBody = RequestBody.create( JSON,json);

            Request.Builder builder = new Request.Builder()
                    .url(url)
                    .post(requestBody);

            if (headers != null && !headers.isEmpty()) {
                headers.forEach(builder::addHeader);
            }

            Request request = builder.build();
            okHttpClient.newCall(request).enqueue(callback);
        } catch (IOException e) {
            callback.onFailure(null, e);
        }
    }

    private void logRequest(String url, Object requestBody) {
        if (log.isInfoEnabled()) {
            try {
                log.info("\n======= 请求开始 =======\n" +
                                "API地址: {}\n" +
                                "请求参数: {}\n" +
                                "======= 请求结束 =======",
                        url,
                        objectMapper.writerWithDefaultPrettyPrinter()
                                .writeValueAsString(requestBody));
            } catch (JsonProcessingException e) {
                log.warn("日志JSON序列化失败", e);
            }
        }
    }

    private void logResponse(String url, int statusCode, String responseBody) {
        if (log.isInfoEnabled()) {
            try {
                // 尝试美化JSON输出
                Object json = objectMapper.readValue(responseBody, Object.class);
                String prettyResponse = objectMapper.writerWithDefaultPrettyPrinter()
                        .writeValueAsString(json);

                log.info("\n======= 响应开始 =======\n" +
                                "API地址: {}\n" +
                                "HTTP状态码: {}\n" +
                                "响应内容: {}\n" +
                                "======= 响应结束 =======",
                        url,
                        statusCode,
                        prettyResponse);
            } catch (Exception e) {
                // 非JSON响应或解析失败时直接输出原始内容
                log.info("\n======= 响应开始 =======\n" +
                                "API地址: {}\n" +
                                "HTTP状态码: {}\n" +
                                "原始响应: {}\n" +
                                "======= 响应结束 =======",
                        url,
                        statusCode,
                        responseBody);
            }
        }
    }
}
