package com.ai.trackwalker.capability.uav;

import com.ai.trackwalker.config.RailProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;

import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;

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

@Component
public class FlightHubAccessClient {
    private final RailProperties properties;
    private final RestTemplate restTemplate;

    public FlightHubAccessClient(RailProperties properties, RestTemplateBuilder builder) {
        this.properties = properties;
        int timeout = Math.max(5, properties.getUavAccess().getTimeoutSeconds());
        this.restTemplate = builder
                .setConnectTimeout(Duration.ofSeconds(Math.min(10, timeout)))
                .setReadTimeout(Duration.ofSeconds(timeout))
                .build();
    }

    public Map<String, Object> get(String path) {
        try {
            Map<?, ?> response = restTemplate.exchange(
                    url(path),
                    HttpMethod.GET,
                    new HttpEntity<>(headers()),
                    Map.class
            ).getBody();
            return unwrap(response);
        } catch (HttpStatusCodeException exception) {
            throw new ResponseStatusException(
                    BAD_GATEWAY,
                    "UAV access service rejected request: " + exception.getResponseBodyAsString(),
                    exception
            );
        } catch (ResourceAccessException exception) {
            throw new ResponseStatusException(
                    SERVICE_UNAVAILABLE,
                    "UAV access service is unavailable: " + exception.getMessage(),
                    exception
            );
        }
    }

    public Map<String, Object> post(String path, Map<String, Object> body) {
        try {
            Map<?, ?> response = restTemplate.postForObject(
                    url(path),
                    new HttpEntity<>(body, headers()),
                    Map.class
            );
            return unwrap(response);
        } catch (HttpStatusCodeException exception) {
            throw new ResponseStatusException(
                    BAD_GATEWAY,
                    "UAV access service rejected request: " + exception.getResponseBodyAsString(),
                    exception
            );
        } catch (ResourceAccessException exception) {
            throw new ResponseStatusException(
                    SERVICE_UNAVAILABLE,
                    "UAV access service is unavailable: " + exception.getMessage(),
                    exception
            );
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> unwrap(Map<?, ?> response) {
        if (response == null) return Map.of();
        if (!"0".equals(String.valueOf(response.get("code")))) {
            Object message = response.get("message");
            throw new ResponseStatusException(
                    BAD_GATEWAY,
                    message == null ? "UAV access service business request failed" : String.valueOf(message)
            );
        }
        Object data = response.get("data");
        if (data instanceof Map<?, ?> map) return new LinkedHashMap<>((Map<String, Object>) map);
        return Map.of("value", data);
    }

    private HttpHeaders headers() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("X-Access-Token", properties.getUavAccess().getToken());
        return headers;
    }

    private String url(String path) {
        return properties.getUavAccess().getUrl().replaceAll("/+$", "") + path;
    }
}
