package com.cn.fdapfe.common.utils.http;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpClientUtils {
    private static final String BOUNDARY = "---------------------------" + System.currentTimeMillis();
    private static final String LINE_FEED = "\r\n";
    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 发送包含文件和表单数据的POST请求，返回JSON响应
     * @param apiUrl 请求URL
     * @param params 包含普通字段和File对象的参数映射
     * @return 包含响应结果的Map对象
     * @throws IOException 网络或IO异常
     */
    public static Map<String, Object> sendPostRequest(String apiUrl, Map<String, Object> params) throws IOException {
        URL url = new URL(apiUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        connection.setDoOutput(true);
        connection.setDoInput(true);

        try (OutputStream outputStream = connection.getOutputStream();
             PrintWriter writer = new PrintWriter(
                     new OutputStreamWriter(outputStream, StandardCharsets.UTF_8),
                     true
             )) {

            // 处理所有参数
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                String fieldName = entry.getKey();
                Object value = entry.getValue();

                if (value instanceof File) {
                    // 处理文件参数
                    File file = (File) value;
                    String fileName = file.getName();

                    writer.append("--" + BOUNDARY).append(LINE_FEED);
                    writer.append("Content-Disposition: form-data; name=\"" + fieldName +
                            "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
                    writer.append("Content-Type: application/octet-stream").append(LINE_FEED);
                    writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
                    writer.append(LINE_FEED);
                    writer.flush();

                    try (FileInputStream fileInputStream = new FileInputStream(file)) {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }
                    outputStream.flush();
                    writer.append(LINE_FEED);
                    writer.flush();
                } else {
                    // 处理普通字段
                    writer.append("--" + BOUNDARY).append(LINE_FEED);
                    writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"").append(LINE_FEED);
                    writer.append("Content-Type: text/plain; charset=UTF-8").append(LINE_FEED);
                    writer.append(LINE_FEED);
                    writer.append(value.toString()).append(LINE_FEED);
                    writer.flush();
                }
            }

            // 结束请求
            writer.append("--" + BOUNDARY + "--").append(LINE_FEED);
            writer.flush();
        }

        int responseCode = connection.getResponseCode();
        String responseBody = readResponseBody(connection, responseCode);
        // 解析JSON响应
        try {
            return objectMapper.readValue(responseBody, Map.class);
        } catch (Exception e) {
            // 返回包含错误信息的Map
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("statusCode", responseCode);
            errorResult.put("error", "Failed to parse JSON response");
            errorResult.put("rawResponse", responseBody);
            return errorResult;
        }
    }

    /**
     * 读取HTTP响应体
     */
    private static String readResponseBody(HttpURLConnection connection, int responseCode) throws IOException {
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(
                        responseCode >= 200 && responseCode < 300 ?
                                connection.getInputStream() : connection.getErrorStream(),
                        StandardCharsets.UTF_8
                )
        )) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            return response.toString();
        }
    }
}