package com.fs.erp.service.impl;

import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fs.erp.dto.tl.dto.JstCancelOrderDTO;
import com.fs.erp.dto.tl.dto.JstInventoryPushDTO;
import com.fs.erp.dto.tl.dto.JstLogisticsPushDTO;
import com.fs.erp.dto.tl.TlCreateOrderRequest;
import com.fs.erp.dto.tl.dto.JstRefundGoodsDTO;
import com.fs.erp.service.TlErpOrderService;
import com.fs.his.domain.FsStoreOrder;
import com.fs.his.service.IFsStoreOrderService;
import com.fs.hisStore.domain.FsStoreOrderScrm;
import com.fs.hisStore.service.IFsStoreOrderScrmService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.*;

@Slf4j
@Service
public class TlErpOrderServiceImpl implements TlErpOrderService {


    @Autowired
    private IFsStoreOrderService storeOrderService;

    @Autowired
    private IFsStoreOrderScrmService storeOrderScrmService;

    //测试兔灵ERP
    //@Value("${jst.api.url:https://api.xiangyue.life/api}")

    //生产兔灵ERP
    @Value("${jst.api.url:https://papi.xiangyue.life/api}")
    private String jstApiBaseUrl;

    //兔灵提供密钥
    @Value("${jst.secret.key:xysync_dLsSaheCzK7RU9gd}")
    private String secretKey;

    private final ObjectMapper objectMapper = new ObjectMapper()
            .configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

    @Override
    public Boolean syncOrderToJst(TlCreateOrderRequest request) {
        try {
            String corpId = request.getCorpId();
            List<?> rawData = request.getData();

            List<Map<String, Object>> dataAsMaps = new ArrayList<>();
            for (Object item : rawData) {
                Map<String, Object> map = objectMapper.convertValue(item, Map.class);
                dataAsMaps.add(map);
            }
            //log.info("【dataAsMaps排序前: {}", dataAsMaps);
            long timestamp = Instant.now().getEpochSecond();
            String sortedDataJson = sortAndSerializeData(dataAsMaps);
            //log.info("【sortedDataJson排序后: {}", sortedDataJson);
            String signSource = secretKey + corpId + sortedDataJson + timestamp;
            String sign = DigestUtils.md5Hex(signSource).toLowerCase();

            String url = jstApiBaseUrl + "/v1/mp/sync/order/jst/create?sign=" + sign + "&t=" + timestamp;
            String requestBody = objectMapper.writeValueAsString(request);
            log.info("url传参 sign: {}, t: {}", sign, timestamp);
            log.info("请求URL: {}", url);
            log.info("请求Body: {}", requestBody);
            HttpResponse response = cn.hutool.http.HttpRequest.post(url)
                    .header("Content-Type", "application/json;charset=UTF-8")
                    .body(requestBody)
                    .timeout(10000)
                    .execute();

            if (!response.isOk()) {
                String responseBody = response.body();
                Map<String, List<String>> headers = response.headers(); // 获取所有响应头
                int statusCode = response.getStatus();

                log.error(
                        "HTTP 请求失败 - 状态码: {}, 响应头: {}, 响应体: {}",
                        statusCode,
                        headers,
                        responseBody != null ? responseBody : "无响应体"
                );

                throw new RuntimeException("调用[兔灵]接口失败，状态码: " + statusCode);
            }

            // 解析响应体
            String responseBody = response.body();
            Map<String, Object> result;
            try {
                result = objectMapper.readValue(responseBody, Map.class);
            } catch (Exception e) {
                log.error("无法解析[兔灵]响应体: {}", responseBody, e);
                throw new RuntimeException("[兔灵]返回非 JSON 响应", e);
            }
            // 判断业务状态是否为 "ok"
            String status = (String) result.get("status");
            if (!"ok".equals(status)) {
                String errmsg = (String) result.get("errmsg");
                log.error("[兔灵]业务处理失败，status: {}, errmsg: {}", status, errmsg);
                throw new RuntimeException("[兔灵]同步订单失败: " + (errmsg != null ? errmsg : "未知错误"));
            }
            log.info("订单同步到[兔灵]成功！{}",result);
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void jSTanErpInventoryCallback(JstInventoryPushDTO request) {
        log.info("收到聚水潭[兔灵]库存同步: {}", request);
    }

    @Override
    public void jSTanErpCancelOrderCallback(JstCancelOrderDTO request) {
        log.info("收到聚水潭[兔灵]取消订单: {}", request);
    }
    public void jSTanErpLogisticsCallback(JstLogisticsPushDTO request) {
        // 关键业务字段
        String soId = request.getSoId();       // 外部单号
        String lId = request.getLId();         // 物流单号
        String lcId = request.getLcId();       // 快递公司编码
        String sendDate = request.getSendDate();
        log.info("收到聚水潭[兔灵]物流单号推送: 外部单号:{}, 物流单号:{}, 快递公司编码:{}, 发送时间:{}", soId, lId, lcId, sendDate);
        FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(request.getSoId());
        if (fsStoreOrder != null && fsStoreOrder.getIsPay() == 1) {
            FsStoreOrder map = new FsStoreOrder();
            map.setOrderId(fsStoreOrder.getOrderId());
            map.setExtendOrderId(request.getOId().toString());
            //更新ERP订单号
            storeOrderService.updateFsStoreOrder(map);

            //物流同步
            storeOrderService.deliveryOrder(fsStoreOrder.getOrderCode(),request.getLId()
                    ,request.getLcId(),request.getLogisticsCompany(),request.getSendDate());
        } else {
            FsStoreOrderScrm orderScrm = storeOrderScrmService.selectFsStoreOrderByOrderCode(request.getSoId());
            log.info("准备更新SCRM订单数据orderScrm:{}", orderScrm);
            if (orderScrm != null && orderScrm.getStatus() == 1) {
                FsStoreOrderScrm map = new FsStoreOrderScrm();
                map.setId(orderScrm.getId());
                map.setExtendOrderId(request.getOId().toString());
                //更新ERP订单号
                storeOrderScrmService.updateFsStoreOrder(map);

                //物流同步
                storeOrderScrmService.deliveryOrder(orderScrm.getOrderCode(),request.getLId(),request.getLcId(),request.getLogisticsCompany());
            }
        }

        //遍历处理items
        if (request.getItems() != null) {
            request.getItems().forEach(item -> {
                log.debug("商品项: skuId={}, qty={}", item.getSkuId(), item.getQty());
            });
        }

    }

    @Override
    public void jSTanErpRefundGoodsCallback(JstRefundGoodsDTO request) {
        log.info("收到聚水潭[兔灵]售后收货商品: {}", request);
    }


    /**
     * 递归对 Map 进行按键升序排序（支持嵌套 Map 和 List）
     */
    @SuppressWarnings("unchecked")
    private Object deepSort(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) obj;
            Map<String, Object> sortedMap = new LinkedHashMap<>();
            map.entrySet().stream()
                    .sorted(Map.Entry.comparingByKey())
                    .forEach(entry -> sortedMap.put(entry.getKey(), deepSort(entry.getValue())));
            return sortedMap;
        } else if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            List<Object> newList = new ArrayList<>(list.size());
            for (Object item : list) {
                newList.add(deepSort(item));
            }
            return newList;
        } else {
            return obj;
        }
    }

    /**
     * 对 data 列表进行深度排序并序列化为紧凑 JSON（无空格）
     */
    private String sortAndSerializeData(List<Map<String, Object>> data) throws JsonProcessingException {
        if (data == null || data.isEmpty()) {
            return "[]";
        }
        List<Object> sortedList = new ArrayList<>();
        for (Map<String, Object> item : data) {
            sortedList.add(deepSort(item));
        }
        return objectMapper.writeValueAsString(sortedList);
    }
}
