package com.github.microservice.auth.server.core.util;

import org.springframework.beans.BeanUtils;
import org.springframework.util.StreamUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;

public class FaceUtil {

    public static HttpResponse<String> uploadFs(String url, InputStream inputStream, String detectorBackend) throws Exception {

        // Generate a boundary for multipart/form-data
        String boundary = UUID.randomUUID().toString();

        // Build the multipart body as byte array
        byte[] multipartBody = buildMultipartBody(boundary, Map.of(
                "img", inputStream,
                "detector_backend", detectorBackend
        ));

        // Create the HttpClient instance
        HttpClient client = HttpClient.newHttpClient();

        // Build the HTTP request
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "multipart/form-data; boundary=" + boundary)
                .POST(HttpRequest.BodyPublishers.ofByteArray(multipartBody))
                .build();

        // Send the request and get the response
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // Print the response
        System.out.println("Response Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());
        return response;
    }

    private static byte[] buildMultipartBody(String boundary, Map<String, Object> formData) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        for (Map.Entry<String, Object> entry : formData.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            outputStream.write(("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8));

            if (value instanceof InputStream) {
                InputStream inputStream = (InputStream) value;

                outputStream.write(("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"uploaded_file\"\r\n").getBytes(StandardCharsets.UTF_8));
                outputStream.write("Content-Type: application/octet-stream\r\n\r\n".getBytes(StandardCharsets.UTF_8));

//                byte[] buffer = new byte[8192];
//                int bytesRead;
//                while ((bytesRead = inputStream.read(buffer)) != -1) {
//                    outputStream.write(buffer, bytesRead);
//                }
                StreamUtils.copy(inputStream,outputStream);

                outputStream.write("\r\n".getBytes(StandardCharsets.UTF_8));
            } else {
                outputStream.write(("Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n").getBytes(StandardCharsets.UTF_8));
                outputStream.write((value.toString() + "\r\n").getBytes(StandardCharsets.UTF_8));
            }
        }

        outputStream.write(("--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8));

        return outputStream.toByteArray();
    }
}
