package com.bohuikeji.delivery.backstage.util.capacity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.util.OrderUtils;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import com.gexin.rp.sdk.base.uitls.MD5Util;
import jodd.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.http.MediaType;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 顺丰同城急送工具类
 * @author Admin
 */
@Slf4j
public class SfExpressUtils {

    public static String APP_ID="476965";
    //生产环境：476965
    //测试环境："157666";

    public static String APP_SECRET="a278dc4a4244d317";
    //生产环境：a278dc4a4244d317
    //测试环境："db95c312ab4ae5d3";

    private static final String BASE_HOST="https://united-store-ms.sf-express.com/zt/hd-united-store-openserver";
    //生产环境：https://united-store-ms.sf-express.com/zt/hd-united-store-openserver
    //测试环境：https://united-store-uat-ms.sf-express.com/zt/hd-united-store-openserver;

    /**
     * 月结卡号
     */
    public static String CUS_NUM="4710823237";
    //测试环境：9999999999
    //生产环境：4710823237


    public static String APP_NAME="内蒙古锦贤物流有限公司";


    /**
     * 发件人编码
     */
    public static String SEND_CODE="nmgjxwl";



    /**
     * 创建订单
     */
    public static String URL_ORDER_CREATE=BASE_HOST+"/api/universal/createOrder";

    /**
     * 取消订单
     */
    public static String URL_ORDER_CANCEL=BASE_HOST+"/api/cancel/order";


    /**
     * 订单实时信息查询
     */
    public static String URL_ORDER_DETAIL=BASE_HOST+"/api/order/freight";

    /**
     * 订单实下单结果
     */
    public static String URL_ORDER_RESULT=BASE_HOST+"/api/order/search";

    /**
     * 订单状态流查询
     */
    public static String  URL_ORDER_STATUS=BASE_HOST+"/api/order/routeQuery";

    /**
     * 获取配送员实时坐标接口
     */
    public static String COURIER_LOCATION=BASE_HOST+"/open/api/external/riderlatestposition";


    /**
     * 预估订单费用和时效性
     */
    public static String ORDER_ESTIMATE=BASE_HOST+"/api/order/deliverTm";

    /**
     * 查询快递调度信息
     */
    public static String ORDER_SCHEDULE_INFO=BASE_HOST+"/api/order/schedule";

    @Test
    public void test(){
        System.out.println(orderScheduleInfo("","SF1620417861943"));

    }


    /**
     * 订单计费接口
     * @return
     */
    public static JSONObject orderEstimate(TOrder order){
        AddressVo maAddress=order.getMailingAddress();
        AddressVo receiptAddress=order.getReceiptAddress();
        Integer weight=order.getCargoWeight();
        if (weight==null||weight.compareTo(0)<1){
            weight=1;
        }
        JSONObject body=new JSONObject();
        body.put("srcAddress",maAddress.getAddress()+maAddress.getDetail());
        body.put("destAddress",receiptAddress.getAddress()+receiptAddress.getDetail());
        body.put("weight",weight);
        body.put("expressType",2);
        JSON res=rsHandle(ORDER_ESTIMATE,request(ORDER_ESTIMATE,body));
        return res!=null?(JSONObject)res:null;
    }

    /**
     * 下单
     * @param order
     * @return
     */
    public static JSONObject placeOrder(TOrder order){
        JSONObject body=new JSONObject();
        body.put("customNumber",CUS_NUM);
        body.put("orderNumber",order.getOrderNum());
        body.put("costType",2);
        body.put("senderOrgCode",SEND_CODE);
        body.put("senderCompany","同城急送");
        body.put("senderName",order.getMailingName());
        body.put("senderTel",order.getMailingPhone());
        AddressVo maAddress=order.getMailingAddress();
        body.put("senderAddress",maAddress.getAddress()+maAddress.getDetail());
        AddressVo receiptAddress=order.getReceiptAddress();
        body.put("receiverName",order.getReceiptName());
        body.put("receiverTel",order.getReceiptPhone());
        body.put("receiverAddress",receiptAddress.getAddress()+receiptAddress.getDetail());
        body.put("payMethod",4);
        body.put("expressType",2);
        body.put("needReturnTrackingNumber",0);
        body.put("declaredValue",new BigDecimal(order.getWorthName().replace("元","")).setScale(2, RoundingMode.DOWN));
        LocalDateTime[] times= OrderUtils.getOrSurplusTimeArea(order.getPickTime());
        body.put("sendStartTime",times[0].format(StringUtils.dataTimeFormat));
        body.put("remark",order.getOrderRemarks());
        JSONArray cargoList=new JSONArray();
        JSONObject cargo=new JSONObject();
        cargo.put("name",order.getCargoName());
        BigDecimal wight=new BigDecimal(order.getCargoWeight()).setScale(3, RoundingMode.DOWN);
        if (wight.compareTo(new BigDecimal("0"))<1){
            wight=new BigDecimal("1.000");
        }
        cargo.put("weight",wight);
        cargoList.add(cargo);
        body.put("cargo",cargoList);
        body.put("cargoTotalWeight",wight);
        String res= request(URL_ORDER_CREATE,body);
        return JSON.parseObject(res);
    }


    /**
     * 取消订单
     * @param orderNum 系统订单号
     * @param mailNumber 顺丰订单号
     * @return
     */
    public static JSONObject cancelOrder(String orderNum,String mailNumber){
        JSONObject body=new JSONObject();
        body.put("orderNumber",orderNum);
        body.put("mailNumber",mailNumber);
        JSON res= rsHandle(URL_ORDER_CANCEL,request(URL_ORDER_CANCEL,body));
        return res!=null?(JSONObject)res:null;
    }


    /**
     * 订单详情
     * @param orderNum
     * @param mailNumber
     * @return
     */
    public static JSONObject orderDetail(String orderNum,String mailNumber){
        JSONObject body=new JSONObject();
        body.put("orderNumber",orderNum);
        body.put("mailNumber",mailNumber);
        JSON res=rsHandle(URL_ORDER_DETAIL,request(URL_ORDER_DETAIL,body));
        return res!=null?(JSONObject)res:null;
    }

    /**
     * 查询订单下单结果
     * @param orderNum
     * @return
     */
    public static JSONObject orderCreateResult(String orderNum){
        JSONObject body=new JSONObject();
        body.put("orderNumber",orderNum);
        JSON res=rsHandle(URL_ORDER_RESULT,request(URL_ORDER_RESULT,body));
        return res!=null?(JSONObject)res:null;
    }

    /**
     * 查询订单
     * @param orderNum
     * @param mailNumber
     * @return
     */
    public static JSONArray orderRecord(String orderNum,String mailNumber){
        JSONObject body=new JSONObject();
        body.put("orderNumber",orderNum);
        body.put("mailNumber",mailNumber);
        JSON res=rsHandle(URL_ORDER_STATUS,request(URL_ORDER_STATUS,body));
        return res!=null?(JSONArray)res:null;
    }

    /**
     * 查询快递调度信息
     * @param orderNum
     * @param mailNumber
     * @return
     */
    public static JSONArray orderScheduleInfo(String orderNum,String mailNumber){
        JSONObject body=new JSONObject();
        JSONArray numArray=new JSONArray();
        numArray.add(mailNumber);
        body.put("mailnos",numArray);
        JSON res=rsHandle(ORDER_SCHEDULE_INFO,request(ORDER_SCHEDULE_INFO,body));
        return res!=null?(JSONArray)res:null;
    }


    /**
     * 执行请求
     * @param url 接口地址
     * @param body 参数(仅需业务参数即可，公共参数及签名自动处理)
     * @return 返回接口业务处理结果
     */
    private static String request(String url,JSONObject body){
        List<String> param=new ArrayList<>(4);
        String requestId=UUID.randomUUID().toString();
        String timestamp=String.valueOf(System.currentTimeMillis());
        param.add(timestamp);
        param.add(requestId);
        param.add(APP_ID);
        param.add(APP_SECRET);
        body.put("appId",APP_ID);
        body.put("requestId",requestId);
        body.put("timestamp",timestamp);
        body.put("sign",sign(param));
        String resStr=HttpRequest.post(url).bodyText(body.toJSONString(), MediaType.APPLICATION_JSON_VALUE, "UTF-8").send().bodyText();
        return resStr;
    }

    /**
     * 接口返回值统一处理
     * @param resStr
     * @return
     */
    private static JSON rsHandle(String url,String resStr){
        JSONObject res;
        try{
            res=JSON.parseObject(resStr);
            log.info("######################################:{}",res);
        }catch (Exception e){
            log.error("【顺丰速运接口错误】无法转换JSON格式！接口：{}，返回：{}",url,resStr);
            return null;
        }
        if (res.getIntValue("httpStatus")!=200){
            log.error("【顺丰速运接口错误】业务执行错误，错误编号：{}，错误信息：{}！接口：{}，返回：{}",res.getString("errorCode"),res.getString("message"),url,resStr);
            return null;
        }
        String dataStr=res.getString("data");
        if (StringUtils.isBlank(dataStr)){
            log.error("【顺丰速运接口错误】业务执行成功，但是返回结果为空，接口：{}，返回：{}",url,resStr);
            return null;
        }
        dataStr=dataStr.trim();
        if (dataStr.startsWith("[")&&dataStr.endsWith("]")){
            return res.getJSONArray("data");
        }
        return res.getJSONObject("data");
    }
    /**
     * 签名
     * @param param 待签名参数
     * @return
     */
    private static String sign(List<String> param){
        Collections.sort(param);
        StringBuilder sb = new StringBuilder();
        for (String str : param) {
            sb.append(str);
        }
        try {
            return DigestUtils.md5DigestAsHex(sb.toString().getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            throw new RuntimeException("顺丰速运签名异常");
        }
    }
}