package com.ai.trackwalker.uavaccess.wayline;

import com.ai.trackwalker.uavaccess.config.UavAccessProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

import java.net.URI;
import java.util.Map;

import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE;

@Component
public class FlightHubObjectStorage {
    private final UavAccessProperties properties;

    public FlightHubObjectStorage(UavAccessProperties properties) {
        this.properties = properties;
    }

    public void upload(Map<String, Object> sts, String objectKey, byte[] content, String contentType) {
        String provider = text(sts.get("provider"));
        if (!provider.equalsIgnoreCase("minio") && !provider.equalsIgnoreCase("aws")) {
            throw new ResponseStatusException(
                    SERVICE_UNAVAILABLE,
                    "STS provider " + provider + " requires an additional deployment-specific uploader"
            );
        }
        Map<String, Object> credentials = map(sts.get("credentials"));
        String region = text(sts.get("region"));
        if (region.isBlank()) region = "us-east-1";
        String endpoint = endpoint(text(sts.get("endpoint")));
        AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
                required(credentials, "access_key_id"),
                required(credentials, "access_key_secret"),
                required(credentials, "security_token")
        );
        try (S3Client client = S3Client.builder()
                .endpointOverride(URI.create(endpoint))
                .region(Region.of(region))
                .credentialsProvider(StaticCredentialsProvider.create(sessionCredentials))
                .serviceConfiguration(S3Configuration.builder()
                        .pathStyleAccessEnabled(properties.getFlighthub().isStoragePathStyleAccess())
                        .build())
                .httpClientBuilder(UrlConnectionHttpClient.builder())
                .build()) {
            client.putObject(
                    PutObjectRequest.builder()
                            .bucket(required(sts, "bucket"))
                            .key(objectKey)
                            .contentType(contentType)
                            .contentLength((long) content.length)
                            .build(),
                    software.amazon.awssdk.core.sync.RequestBody.fromBytes(content)
            );
        }
    }

    private String endpoint(String value) {
        if (value.startsWith("http://") || value.startsWith("https://")) return value;
        return "https://" + value;
    }

    private String required(Map<String, Object> values, String key) {
        String value = text(values.get(key));
        if (value.isBlank()) {
            throw new ResponseStatusException(SERVICE_UNAVAILABLE, "STS response is missing " + key);
        }
        return value;
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> map(Object value) {
        return value instanceof Map<?, ?> map ? (Map<String, Object>) map : Map.of();
    }

    private String text(Object value) {
        return value == null ? "" : String.valueOf(value);
    }
}
