package com.erp.logistics.service.adapter;

import cn.hutool.crypto.digest.DigestUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * 物流商适配器基类
 */
@Slf4j
public abstract class AbstractCarrierAdapter implements CarrierAdapter {

    protected static final ObjectMapper objectMapper = new ObjectMapper();
    protected static final DateTimeFormatter DT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Override
    public boolean verifySign(Map<String, Object> data, String sign) {
        if (sign == null || sign.isEmpty()) {
            return false;
        }
        // 各物流商签名验证逻辑由子类实现
        return doVerifySign(data, sign);
    }

    /**
     * 子类实现具体的签名验证
     */
    protected abstract boolean doVerifySign(Map<String, Object> data, String sign);

    /**
     * 获取签名密钥
     */
    protected abstract String getSecretKey();

    /**
     * MD5签名验证
     */
    protected boolean verifyMd5Sign(Map<String, Object> data, String sign, String... ignoreKeys) {
        StringBuilder sb = new StringBuilder();
        // 按字典序拼接参数
        data.entrySet().stream()
                .filter(e -> !containsIgnore(e.getKey(), ignoreKeys))
                .sorted(Map.Entry.comparingByKey())
                .forEach(e -> sb.append(e.getKey()).append("=").append(e.getValue()).append("&"));
        sb.append("key=").append(getSecretKey());
        String md5 = DigestUtil.md5Hex(sb.toString()).toUpperCase();
        return md5.equals(sign.toUpperCase());
    }

    private boolean containsIgnore(String key, String[] ignoreKeys) {
        for (String ignoreKey : ignoreKeys) {
            if (ignoreKey.equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 解析时间字符串
     */
    protected LocalDateTime parseTime(String timeStr) {
        if (timeStr == null || timeStr.isEmpty()) {
            return null;
        }
        try {
            if (timeStr.contains(":")) {
                return LocalDateTime.parse(timeStr, DT_FORMATTER);
            } else {
                return LocalDateTime.parse(timeStr + " 00:00:00", DT_FORMATTER);
            }
        } catch (Exception e) {
            log.warn("解析时间失败: {}", timeStr, e);
            return null;
        }
    }

    /**
     * 将对象转为JSON字符串
     */
    protected String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("JSON序列化失败", e);
            return null;
        }
    }
}
