package com.zsElectric.boot.common.util.electric;

import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.zsElectric.boot.common.constant.ConnectivityConstants;
import com.zsElectric.boot.common.util.AESCryptoUtils;
import com.zsElectric.boot.common.util.HmacMD5Util;
import com.zsElectric.boot.common.util.OkHttpUtil;
import com.zsElectric.boot.common.util.SequenceGenUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class ChargingUtil {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Resource
    private ElectricTokenManager tokenManager;
    @Resource
    private OkHttpUtil okHttpUtil;

    /**
     * 请求封装
     * @param url
     * @param queryParms
     * @param tokenRequired
     * @return
     */
    public JsonNode chargingRequest(String url, Map<String,Object> queryParms,boolean tokenRequired){
        Map<String, String> headers = new HashMap<>();
        if(tokenRequired){
            headers.put("Authorization", "Bearer " + tokenManager.getValidAccessToken());
        }
        try {
            RequestParmsEntity requestParms = new RequestParmsEntity();
            SequenceGenUtil.SequenceResult result = SequenceGenUtil.generate();

            requestParms.setOperatorID(ConnectivityConstants.OPERATOR_ID);
            requestParms.setData(AESCryptoUtils.encrypt(objectMapper.writeValueAsString(queryParms),ConnectivityConstants.PLATFORM_DATA_SECRET,
                            ConnectivityConstants.PLATFORM_DATA_SECRET_IV));
            requestParms.setTimeStamp(result.getTimestamp());
            requestParms .setSeq(result.getSequence());
            requestParms.setSig(HmacMD5Util.genSign(requestParms.getOperatorID(),requestParms.getData(),
                            requestParms.getTimeStamp(),
                            requestParms.getSeq(),ConnectivityConstants.PLATFORM_SIG_SECRET));

            String requestJson = objectMapper.writeValueAsString(requestParms);
            log.info("调用第三方接口，URL: {}, 请求参数: {}", url, requestJson);
            JsonNode response = okHttpUtil.doPostForm(url, requestJson, headers);

            if (Objects.isNull(response)) {
                log.error("调用第三方接口返回为空，URL: {}", url);
                return null;
            }
            log.info("调用第三方接口成功，URL: {}, 响应: {}", url, response);
            return response;
        }catch (Exception e){
            log.error("调用第三方接口发生异常，URL: {}", url, e);
            throw new RuntimeException("调用第三方接口发生异常: " + e.getMessage(), e);
        }
    }

    /**
     * 响应解密
     * @param response
     * @return
     */
    public JsonNode responseDecode(JsonNode response){

        try {
            if (Objects.isNull(response)) {
                log.error("第三方接口响应数据为空");
                return null;
             }
            ResponseParmsEntity responseParms = objectMapper.readValue(response.toString(), ResponseParmsEntity.class);
            String data = responseParms.getRet() + responseParms.getMsg() + responseParms.getData();
            boolean verify = HmacMD5Util.verify(data, ConnectivityConstants.PLATFORM_SIG_SECRET, responseParms.getSig());
            if (!verify) {
                log.error("第三方接口响应数据签名验证失败");
                return null;
            }
            if (responseParms.getRet() != 0){
                switch (responseParms.getRet()) {
                    case -1:
                        log.error("系统繁忙,此时请求方稍后重试");
                        break;
                    case 4001:
                        log.error("签名错误");
                        break;
                    case 4002:
                        log.error("Token错误");
                        break;
                    case 4003:
                        log.error("参数不合法,缺少必需的示例:OperatorID、Sig、TimeStamp、Data、Seq五个参数");
                        break;
                    case 4004:
                        log.error("请求的业务参数不合法,各接口定义自己的必须参数");
                        break;
                    case 500:
                        log.error("系统错误");
                        break;
                }
            }
            String decodeData = AESCryptoUtils.decrypt(responseParms.getData(), ConnectivityConstants.PLATFORM_DATA_SECRET,
                    ConnectivityConstants.PLATFORM_DATA_SECRET_IV);
            return objectMapper.readTree(decodeData);
        }catch (Exception e){
            throw new RuntimeException("第三方接口响应发生异常", e);
        }
    }


    /**
     * 统一解密接口数据-己方响应
     * */
    public String decryptData(String data) throws Exception {
        return AESCryptoUtils.decrypt(data, ConnectivityConstants.DATA_SECRET, ConnectivityConstants.DATA_SECRET_IV);
    }

    /**
     * 统一加密接口数据-己方响应
     * */
    public String encryptData(String data) throws Exception {
        return AESCryptoUtils.encrypt(data, ConnectivityConstants.DATA_SECRET, ConnectivityConstants.DATA_SECRET_IV);
    }
}
