package com.haobang.interlocking;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 探针联动API客户端
 * 用于调用syslog-consumer模块提供的REST API
 */
@Component
public class InterlockingApiClient {

    private static final Logger logger = LoggerFactory.getLogger(InterlockingApiClient.class);

    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${interlocking.api-key:a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6}")
    private String apiKey;

    @Value("${interlocking.api.base-url:http://localhost:8089/xdrservice/interlocking}")
    private String baseUrl;

    /**
     * 获取待执行的封禁指令
     * @param probeId 探针ID
     * @return 指令列表
     */
    public List<Map<String, Object>> getPendingCommands(Long probeId) {
        String url = baseUrl + "/cmd/pending?probeId=" + probeId;
        try {
            String response = doGet(url);
            JsonNode jsonNode = objectMapper.readTree(response);
            if (jsonNode.has("code") && jsonNode.get("code").asInt() == 200) {
                JsonNode dataNode = jsonNode.get("data");
                List<Map<String, Object>> commands = new ArrayList<>();
                if (dataNode.isArray()) {
                    for (JsonNode node : dataNode) {
                        commands.add(objectMapper.convertValue(node, Map.class));
                    }
                }
                return commands;
            }
            logger.warn("获取待执行指令失败: {}", response);
            return Collections.emptyList();
        } catch (Exception e) {
            logger.error("获取待执行指令异常: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    /**
     * 更新指令状态为执行中
     * @param cmdId 指令ID
     * @return 是否成功
     */
    public boolean updateStatusToExecuting(Long cmdId) {
        String url = baseUrl + "/cmd/" + cmdId + "/status/executing";
        try {
            String response = doPut(url, null);
            JsonNode jsonNode = objectMapper.readTree(response);
            return jsonNode.has("code") && jsonNode.get("code").asInt() == 200;
        } catch (Exception e) {
            logger.error("更新指令状态为执行中失败: cmdId={}, error={}", cmdId, e.getMessage());
            return false;
        }
    }

    /**
     * 更新指令状态为执行完成
     * @param cmdId 指令ID
     * @return 是否成功
     */
    public boolean updateStatusToCompleted(Long cmdId) {
        String url = baseUrl + "/cmd/" + cmdId + "/status/completed";
        try {
            String response = doPut(url, null);
            JsonNode jsonNode = objectMapper.readTree(response);
            return jsonNode.has("code") && jsonNode.get("code").asInt() == 200;
        } catch (Exception e) {
            logger.error("更新指令状态为执行完成失败: cmdId={}, error={}", cmdId, e.getMessage());
            return false;
        }
    }

    /**
     * 更新指令状态为执行失败
     * @param cmdId 指令ID
     * @param errorMessage 错误信息
     * @return 是否成功
     */
    public boolean updateStatusToFailed(Long cmdId, String errorMessage) {
        String url = baseUrl + "/cmd/" + cmdId + "/status/failed";
        try {
            Map<String, Object> body = new HashMap<>();
            body.put("errorMessage", errorMessage);
            String response = doPut(url, body);
            JsonNode jsonNode = objectMapper.readTree(response);
            return jsonNode.has("code") && jsonNode.get("code").asInt() == 200;
        } catch (Exception e) {
            logger.error("更新指令状态为执行失败失败: cmdId={}, error={}", cmdId, e.getMessage());
            return false;
        }
    }

    /**
     * 批量插入封禁记录
     * @param logs 封禁记录列表
     * @return 是否成功
     */
    public boolean batchInsertLogs(List<Map<String, Object>> logs) {
        String url = baseUrl + "/log/batch";
        try {
            Map<String, Object> request = new HashMap<>();
            request.put("logs", logs);
            String response = doPost(url, request);
            JsonNode jsonNode = objectMapper.readTree(response);
            return jsonNode.has("code") && jsonNode.get("code").asInt() == 200;
        } catch (Exception e) {
            logger.error("批量插入封禁记录失败: error={}", e.getMessage());
            return false;
        }
    }

    /**
     * 执行GET请求
     */
    private String doGet(String url) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-API-KEY", apiKey);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        return response.getBody();
    }

    /**
     * 执行PUT请求
     */
    private String doPut(String url, Map<String, Object> body) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("X-API-KEY", apiKey);
        
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, entity, String.class);
        return response.getBody();
    }

    /**
     * 执行POST请求
     */
    private String doPost(String url, Map<String, Object> body) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("X-API-KEY", apiKey);
        
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        return response.getBody();
    }

    public String getApiKey() { return apiKey; }
    public void setApiKey(String apiKey) { this.apiKey = apiKey; }
    public String getBaseUrl() { return baseUrl; }
    public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
}
