package com.ai.trackwalker.capability.uav;

import com.ai.trackwalker.common.Jsonb;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;

import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

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

@Component
public class FlightHub2UavVendorAdapter implements UavVendorAdapter {
    private final FlightHubAccessClient client;

    public FlightHub2UavVendorAdapter(FlightHubAccessClient client) {
        this.client = client;
    }

    @Override
    public String vendorCode() {
        return "FLIGHTHUB2";
    }

    @Override
    public Map<String, Object> checkConnection(Map<String, Object> connection) {
        String id = String.valueOf(connection.get("id"));
        return client.get("/api/v1/connection/health?connection_id=" + encode(id));
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> synchronizeDevices(Map<String, Object> connection) {
        String id = String.valueOf(connection.get("id"));
        Map<String, Object> result = client.get("/api/v1/devices?connection_id=" + encode(id));
        Object devices = result.get("devices");
        if (!(devices instanceof List<?> list)) return List.of();
        List<Map<String, Object>> normalized = new ArrayList<>();
        for (Object item : list) {
            if (item instanceof Map<?, ?> map) normalized.add(new LinkedHashMap<>((Map<String, Object>) map));
        }
        return normalized;
    }

    @Override
    public Map<String, Object> prepareRoute(Map<String, Object> connection, Map<String, Object> route) {
        String connectionId = text(connection.get("id"));
        String routeVersionId = text(route.get("route_version_id"));
        Map<String, Object> waylineRequest = new LinkedHashMap<>();
        waylineRequest.put("connection_id", connectionId);
        waylineRequest.put("route_version_id", routeVersionId);
        waylineRequest.put("name", text(route.get("name")));
        waylineRequest.put("waypoints", mapList(route.get("waypoints")));
        waylineRequest.put("flight_parameters", map(route.get("flight_parameters")));
        Map<String, Object> artifact = client.post("/api/v1/waylines", waylineRequest);
        if ("IMPORTING".equals(text(artifact.get("import_state")))) {
            artifact = client.get(
                    "/api/v1/waylines/" + encode(routeVersionId)
                            + "?connection_id=" + encode(connectionId)
                            + "&refresh=true"
            );
        }
        return artifact;
    }

    @Override
    public Map<String, Object> dispatchMission(Map<String, Object> mission, Map<String, Object> route) {
        String connectionId = text(mission.get("connection_id"));
        Map<String, Object> connection = Map.of("id", connectionId);
        Map<String, Object> artifact = prepareRoute(connection, route);
        String importState = text(artifact.get("import_state"));
        if ("IMPORTING".equals(importState)) {
            throw new ResponseStatusException(
                    CONFLICT,
                    "航线已上传司空 2，正在异步导入；导入完成后请重新下发任务"
            );
        }
        if (!"IMPORTED".equals(importState)) {
            throw new ResponseStatusException(
                    CONFLICT,
                    "司空 2 航线导入失败：" + artifact.getOrDefault("import_detail", artifact)
            );
        }

        Map<String, Object> request = new LinkedHashMap<>();
        request.put("connection_id", connectionId);
        request.put("platform_mission_id", mission.get("mission_id"));
        request.put("platform_task_id", mission.get("task_id"));
        request.put("route_version_id", route.get("route_version_id"));
        request.put("device_sn", mission.get("vendor_device_id"));
        request.put("dock_sn", mission.get("dock_vendor_device_id"));
        request.put("name", "铁路巡检-" + mission.get("task_id"));
        request.put("planned_start_at", mission.get("planned_start_at"));
        request.put("idempotency_key", mission.getOrDefault("idempotency_key", "dispatch-" + mission.get("mission_id")));
        request.put("options", map(route.get("flight_parameters")));
        return client.post("/api/v1/missions", request);
    }

    @Override
    public Map<String, Object> executeCommand(
            Map<String, Object> mission,
            String command,
            Map<String, Object> parameters
    ) {
        Map<String, Object> request = new LinkedHashMap<>();
        request.put("command", command);
        request.put("idempotency_key", parameters.getOrDefault(
                "idempotency_key",
                command + "-" + mission.get("id") + "-" + Instant.now().toEpochMilli()
        ));
        request.put("platform_command_id", parameters.get("platform_command_id"));
        request.put("requested_by", parameters.get("requested_by"));
        request.put("reason", parameters.get("reason"));
        request.put("parameters", parameters);
        return client.post("/api/v1/missions/" + encode(text(mission.get("id"))) + "/commands", request);
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> map(Object value) {
        if (value instanceof Map<?, ?> map) return new LinkedHashMap<>((Map<String, Object>) map);
        if (value instanceof String json && !json.isBlank()) return Jsonb.map(json);
        return Map.of();
    }

    @SuppressWarnings("unchecked")
    private List<Map<String, Object>> mapList(Object value) {
        if (value instanceof List<?> list) return (List<Map<String, Object>>) list;
        if (value instanceof String json && !json.isBlank()) return Jsonb.mapList(json);
        return List.of();
    }

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

    private String encode(String value) {
        return java.net.URLEncoder.encode(value, java.nio.charset.StandardCharsets.UTF_8);
    }
}
