package com.liquidnet.service.goblin.express.kuaidi100;

import com.google.gson.Gson;
import com.kuaidi100.sdk.api.AutoNum;
import com.kuaidi100.sdk.api.QueryTrackMap;
import com.kuaidi100.sdk.api.SubscribeWithMap;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.*;
import com.kuaidi100.sdk.response.AutoNumResp;
import com.kuaidi100.sdk.response.QueryTrackMapResp;
import com.kuaidi100.sdk.response.SubscribeResp;
import com.kuaidi100.sdk.utils.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 快递100 客户端：地图查询 / 地图订阅 / 单号识别
 */
@Slf4j
@Component
public class Kuaidi100Client {

    public static final String RESULT_V2_QUERY = "5";
    /** 订阅接口高级状态对应 resultv2=4（与查询侧 5 能力对齐） */
    public static final String RESULT_V2_SUBSCRIBE = "4";

    private final Gson gson = new Gson();

    @Value("${liquidnet.express.kuaidi100.customer:}")
    private String customer;

    @Value("${liquidnet.express.kuaidi100.key:}")
    private String key;

    @Value("${liquidnet.express.kuaidi100.salt:}")
    private String salt;

    @Value("${liquidnet.express.kuaidi100.callbackurl:}")
    private String callbackurl;

    @Value("${liquidnet.express.kuaidi100.from:北京市朝阳区}")
    private String defaultFrom;

    public String getCallbackurl() {
        return callbackurl;
    }

    public String getSalt() {
        return salt;
    }

    public String getDefaultFrom() {
        return defaultFrom;
    }

    public boolean isConfigured() {
        return StringUtils.isNotBlank(customer) && StringUtils.isNotBlank(key);
    }

    /**
     * 地图轨迹主动查询（含文字轨迹 + trailUrl）
     */
    public QueryTrackMapResp queryMapTrack(String com, String num, String phone, String from, String to) throws Exception {
        QueryTrackParam queryTrackParam = new QueryTrackParam();
        queryTrackParam.setCom(com);
        queryTrackParam.setNum(num);
        queryTrackParam.setPhone(phone);
        queryTrackParam.setFrom(StringUtils.isNotBlank(from) ? from : defaultFrom);
        queryTrackParam.setTo(to);
        queryTrackParam.setResultv2(RESULT_V2_QUERY);
        queryTrackParam.setShow("0");
        queryTrackParam.setOrder("desc");

        String param = gson.toJson(queryTrackParam);
        QueryTrackReq queryTrackReq = new QueryTrackReq();
        queryTrackReq.setParam(param);
        queryTrackReq.setCustomer(customer);
        queryTrackReq.setSign(SignUtils.querySign(param, key, customer));

        IBaseClient baseClient = new QueryTrackMap();
        HttpResult result = baseClient.execute(queryTrackReq);
        log.info("[kuaidi100] queryMapTrack status={}, body={}", result.getStatus(), result.getBody());
        if (result.getStatus() == 200 && StringUtils.isNotBlank(result.getBody())) {
            return gson.fromJson(result.getBody(), QueryTrackMapResp.class);
        }
        return null;
    }

    /**
     * 地图轨迹订阅
     */
    public SubscribeResp subscribeWithMap(String com, String num, String phone, String from, String to,
                                          String callbackUrlWithParams) throws Exception {
        SubscribeParameters subscribeParameters = new SubscribeParameters();
        subscribeParameters.setCallbackurl(callbackUrlWithParams);
        subscribeParameters.setPhone(phone);
        subscribeParameters.setResultv2(RESULT_V2_SUBSCRIBE);
        if (StringUtils.isNotBlank(salt)) {
            subscribeParameters.setSalt(salt);
        }

        SubscribeParam subscribeParam = new SubscribeParam();
        subscribeParam.setParameters(subscribeParameters);
        subscribeParam.setCompany(com);
        subscribeParam.setNumber(num);
        subscribeParam.setFrom(StringUtils.isNotBlank(from) ? from : defaultFrom);
        subscribeParam.setTo(to);
        subscribeParam.setKey(key);

        SubscribeReq subscribeReq = new SubscribeReq();
        subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
        subscribeReq.setParam(gson.toJson(subscribeParam));

        IBaseClient subscribe = new SubscribeWithMap();
        HttpResult httpResult = subscribe.execute(subscribeReq);
        log.info("[kuaidi100] subscribeWithMap status={}, body={}", httpResult.getStatus(), httpResult.getBody());
        if (httpResult.getStatus() == 200 && StringUtils.isNotBlank(httpResult.getBody())) {
            return gson.fromJson(httpResult.getBody(), SubscribeResp.class);
        }
        return null;
    }

    /**
     * 单号识别快递公司（取置信度最高的第一个）
     */
    public AutoNumResp autoComDetail(String mailNo) {
        try {
            AutoNumReq autoNumReq = new AutoNumReq();
            autoNumReq.setKey(key);
            autoNumReq.setNum(mailNo);
            AutoNum autoNum = new AutoNum();
            List<AutoNumResp> list = autoNum.getComByNumList(autoNumReq);
            if (list != null && !list.isEmpty()) {
                return list.get(0);
            }
        } catch (Exception e) {
            log.error("[kuaidi100] autoComDetail error, mailNo={}", mailNo, e);
        }
        return null;
    }

    /**
     * 单号识别快递公司编码（取置信度最高的第一个）
     */
    public String autoComByNum(String mailNo) {
        AutoNumResp resp = autoComDetail(mailNo);
        return resp == null ? null : resp.getComCode();
    }

    public boolean verifyCallbackSign(String param, String sign) {
        if (StringUtils.isBlank(sign)) {
            return StringUtils.isBlank(salt);
        }
        String ourSign = SignUtils.sign(param + (salt == null ? "" : salt));
        return ourSign.equalsIgnoreCase(sign);
    }
}
