package org.ta.pddserver.utils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.ta.pddserver.model.pddjy.request.JYBaseRequestModel;
import org.ta.pddserver.model.pddlg.request.LGBaseModel;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class PddSignTool {

    public static boolean verifySign(JYBaseRequestModel requestParam, String secret) {
        String sign = requestParam.getSign();
        if (sign == null) {
            return false;
        }
        return sign.equals(PddSignTool.generateSign(requestParam, secret));
    }

    public static boolean verifySignFromBody(String body, String secret, String sign) {
        if (sign == null) {
            return false;
        }
        return sign.equals(PddSignTool.generateSignFromString(body, secret));
    }

    public static String generateSignFromString(String body, String secret) {
        return MD5Util.encode(secret + body + secret).toUpperCase();
    }

    /**
     * 生成签名（核心方法）
     * 算法逻辑：参数按key升序排序 → 拼接为key=value&key=value形式 → 拼接secret → MD5加密 → 转大写
     */
    public static String generateSign(Object obj, String secret) {
        HashMap params = ObjectCommonTool.objectToMap(obj);
        return generateSignFromMap(params, secret);
    }

    /**
     * 生成签名（核心方法）
     * 算法逻辑：参数按key升序排序 → 拼接为key=value&key=value形式 → 拼接secret → MD5加密 → 转大写
     */
    public static String generateSignFromMap(Map<String, Object> params, String secret) {
        // 1. 移除sign（避免参与签名计算）
        params.remove("sign");
        // 2. 过滤空值参数
        Map<String, Object> nonNullParams = params.entrySet().stream()
                .filter(entry -> entry.getValue() != null && !entry.getValue().toString().isEmpty())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        // 3. 参数按key的ASCII码升序排序
        List<String> sortedKeys = new ArrayList<>(nonNullParams.keySet());
        Collections.sort(sortedKeys);
        // 4. 拼接参数串
        StringBuilder paramStr = new StringBuilder();
        paramStr.append(secret);
        for (String key : sortedKeys) {
            paramStr.append(key).append(JSON.toJSON(nonNullParams.get(key)));
        }
        // 5. 拼接appSecret（注意末尾无&）
        paramStr.append(secret);
        log.info("string = {}", paramStr.toString());
        // 6. MD5加密并转大写
        return MD5Util.encode(paramStr.toString()).toUpperCase();
    }

    public static boolean verifyLGSign(LGBaseModel requestParam, String secret) {
        String sign = requestParam.getSign();
        if (sign == null) {
            return false;
        }
        return sign.equals(PddSignTool.generateSign(requestParam, secret));
    }
}
