package com.ruoyi.web.controller.chenyanlogin.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Component
public class ZhwlCaller {

    private static final Logger log = LoggerFactory.getLogger(ZhwlCaller.class);

//    @Value("${cloud.platform.appKey}")
    private String appKey = "Kg2pE5V0";

//    @Value("${cloud.platform.appSecret}")
    private String appSecret = "7a3bbfd6656e1bdef7290b714c1d1c73578a4ce2";

//    @Value("${cloud.platform.baseUrl}")
    private String baseUrl = "https://webapi.nbiotyun.com"; // e.g., http://domain/api/v1

    private final RestTemplate restTemplate = new RestTemplate();

    // 接口路径常量（便于管理）
    private static final String GET_DEVICE_LIST_PATH = "/api/v1/dev/getList";

    /**
     * 公共方法：构建带认证信息的请求头
     *
     * @param path      原始请求路径（如：/dev/getList），用于签名
     * @param timestamp 时间戳（毫秒）
     * @return HttpHeaders
     */
    private HttpHeaders buildCommonHeaders(String path, long timestamp) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("appKey", appKey);
        headers.set("timestamp", String.valueOf(timestamp));

        // 签名：MD5(path + timestamp + appSecret)
        String signatureSource = path + timestamp + appSecret;
        String signature = DigestUtils.md5DigestAsHex(signatureSource.getBytes(StandardCharsets.UTF_8));
        headers.set("signature", signature);
        log.debug("signatureSource:{}", signatureSource);
        log.debug("headers:{}", JSON.toJSONString(headers));
        return headers;
    }

    /**
     * 通用 POST 请求模板方法（可扩展）
     */
    private ResponseEntity<String> postForString(String endpointPath, Object requestBody) {
        String url = baseUrl + endpointPath;
        long timestamp = System.currentTimeMillis();

        try {
            // 序列化请求体
            String jsonBody = JSON.toJSONString(requestBody);

            // 构建请求头
            HttpHeaders headers = buildCommonHeaders(endpointPath, timestamp);
            headers.setContentType(MediaType.APPLICATION_JSON);
            // 明确接受 JSON，但即使返回 text/html 也能拿到字符串
            headers.setAccept(Collections.singletonList(MediaType.ALL)); // 接受任意类型

            // 构建请求实体
            HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);

            // 使用 String.class 接收响应体，不管 Content-Type 是什么
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
            log.debug(response.toString());
            return response;
//            return new ResponseEntity<>(null);
        } catch (Exception e) {
            throw new RuntimeException("调用接口失败: " + url, e);
        }
    }
    private ResponseEntity<Map<String, Object>> postForMap(String endpointPath, Object requestBody) {
        String url = baseUrl + endpointPath;
        long timestamp = System.currentTimeMillis();

        try {
            String jsonBody = JSON.toJSONString(requestBody);
            HttpHeaders headers = buildCommonHeaders(endpointPath, timestamp);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

            HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);

            ParameterizedTypeReference<Map<String, Object>> typeRef =
                    new ParameterizedTypeReference<Map<String, Object>>() {};

            ResponseEntity<Map<String, Object>> response = restTemplate.exchange(url, HttpMethod.POST, entity, typeRef);

            return response;

        } catch (Exception e) {
            throw new RuntimeException("调用接口失败: " + url, e);
        }
    }
    // ==================== 接口调用方法区 ====================

    /**
     * 查询设备列表
     */
    public DeviceRespDTO getDeviceList(DeviceListQueryVO queryVO) {
        ResponseEntity<String> response = postForString(GET_DEVICE_LIST_PATH, queryVO);
        //1. 检查 HTTP 状态码
        if (!response.getStatusCode().is2xxSuccessful()) {
            log.info("HTTP {} - 请求失败，响应内容: {}",response.getStatusCode() ,response.getBody());
            return new DeviceRespDTO();
        }

        String body = response.getBody();
        if (body == null || body.trim().isEmpty()) {
            log.info("云平台返回空响应体");
            return new DeviceRespDTO();
        }

        //2. 打印原始响应（调试用，上线可关闭）
         log.debug("原始响应: {}", body);

        try {
            //3. 先解析外层 JSON
            Map<String, Object> map = JSON.parseObject(body, Map.class);

            //4. 提取 code、success
            String code = (String) map.get("code");
            Boolean success = (Boolean) map.get("success");

            Object messageObj = map.get("message");
            if (!(messageObj instanceof Map)) {
                throw new RuntimeException("响应中的 message 字段不是对象类型: " + messageObj);
            }

            Map<String, Object> messageMap = (Map<String, Object>) messageObj;

            //5. 构建返回 DTO
            DeviceRespDTO respDTO = new DeviceRespDTO();
            respDTO.setPageSize((Integer) messageMap.get("pageSize"));
            respDTO.setPageCount((Integer) messageMap.get("pageCount"));
            respDTO.setCurrentPage((Integer) messageMap.get("currentPage"));
            respDTO.setTotal((Integer) messageMap.get("total"));

            //6. 解析 data 列表（关键：用 Fastjson 转成 List<DeviceItemDTO>）
            Object dataList = messageMap.get("data");
            if (dataList instanceof List) {
                respDTO.setData(JSON.parseArray(JSON.toJSONString(dataList), DeviceRespDTO.DeviceItemDTO.class));
            } else {
                respDTO.setData(new ArrayList<>());
            }

            return respDTO;

        } catch (Exception e) {
            throw new RuntimeException("解析响应数据失败，响应内容: " + body, e);
        }
    }


    @Data
    public static class DeviceListQueryVO {

        private String deviceModelName;

        private Integer pageNum = 10;

        private Integer pageSize = 1; // 最大值可在业务层校验 1-100

        private String startTime;
        private String endTime;

        private Integer fullFlag = 0; // 0: 本级, 1: 所有

        private Integer state; // 设备状态
        private Integer registerSign; // 入网注册标志
    }

    @Data
    public static class DeviceRespDTO {

        private List<DeviceItemDTO> data;

        private Integer pageSize;
        private Integer pageCount;
        private Integer currentPage;
        private Integer total;

        @Data
        public static class DeviceItemDTO implements Serializable {
            private Long deviceId;
            private String deviceImei;
            private String deviceImsi;
            private String iccid;
            private String deviceTypeName;
            private String deviceModelName;
            private Integer registerSign;
            private Integer state;
            private Double latitude;
            private Double longitude;
            private String installAddress;
            private String contact;
            private String phonenumber;
            private String companyName;
            private String floorName;
            private String buildingName;
            private String roomName;
            private String region;

            @JSONField(name = "createTime")
            private String createTime;

            @JSONField(name = "updateTime")
            private String updateTime;
        }
    }

}
