package com.cftech.waybill.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.order.model.Order;
import com.cftech.orderdetail.model.OrderDetails;
import com.cftech.waybill.model.Waybill;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * Created by 16444 on 2020/10/21.
 */
@Slf4j
public class ExpressOrderInfoUtils {

    private static final String language = "zh-CN";

    private static final String countryCode = "CN";

    private static final String currencyCode = "HKD";

    private static final String payMethod = "1";//寄方付

    /**
     * 生成打印面单
     * @param order
     * @param orderDetails
     * @param waybillObj
     * @return
     */
    public static JSONObject generateBillPrinterObj(Order order, List<OrderDetails> orderDetails, Waybill waybillObj) {
        JSONObject billPrinter = new JSONObject();
        try {
            billPrinter.put("appId", SystemConfig.p.getProperty("sf.partnerID"));//顾客编码
            billPrinter.put("appKey", SystemConfig.p.getProperty("sf.checkWord"));//校验码

            billPrinter.put("mailNo", waybillObj.getWaybillNo());//运单号
            billPrinter.put("expressType", 1);//1-标准快递 2-顺丰标快（陆运）5-顺丰次晨 6-顺丰即日
            billPrinter.put("payMethod", 1);//付款方式 1-寄付 2-到付 3-第三方付
            billPrinter.put("orderNo", order.getNumber());//订单号

            billPrinter.put("monthAccount", SystemConfig.p.getProperty("sf.monthlyCard"));

            //寄件人信息
            billPrinter.put("deliverCompany", "扬州诺康大药房有限公司");
            billPrinter.put("deliverName", "吴赵龙");
            billPrinter.put("deliverMobile", "15150808407");
            billPrinter.put("deliverProvince", "江苏省");
            billPrinter.put("deliverCity", "扬州市");
            billPrinter.put("deliverCounty", "邗江区");
            billPrinter.put("deliverAddress", "科技园路18号");
            billPrinter.put("deliverShipperCode", "225000");

            //收件人信息
            billPrinter.put("consignerName", waybillObj.getContact());
            billPrinter.put("consignerMobile", waybillObj.getMobile());
            billPrinter.put("consignerProvince", waybillObj.getProvince());
            billPrinter.put("consignerCity", waybillObj.getCity());
            if (StringUtils.isNoneBlank(waybillObj.getCounty()) && waybillObj.getCounty().length() >= 2) {
                StringBuilder county = new StringBuilder(waybillObj.getCounty());
                billPrinter.put("consignerCounty", county.replace(1, 2, "*"));
            } else {
                billPrinter.put("consignerCounty", "");
            }
            if (StringUtils.isNoneBlank(waybillObj.getAddress()) && waybillObj.getAddress().length() >= 2) {
                StringBuilder address = new StringBuilder(waybillObj.getAddress());
                billPrinter.put("consignerAddress", address.replace(0, 2, "*"));
            } else {
                billPrinter.put("consignerAddress", "");
            }
            billPrinter.put("consignerShipperCode", "225000");

            //billPrinter.put("totalFee", "");//费用合计

            billPrinter.put("encryptMobile", true);//加密电话
            billPrinter.put("encryptCustName", true);//加密收寄人信息
            billPrinter.put("mainRemark", "");//主运单备注信息

            //商品信息
            JSONArray cargoInfoDtoList = new JSONArray();
            for (OrderDetails ord: orderDetails) {
                JSONObject cargoInfo = new JSONObject();
                cargoInfo.put("cargo", ord.getProductName());
                cargoInfo.put("cargoCount", ord.getDrugsNum());
                cargoInfo.put("cargoUnit", "盒");
                cargoInfo.put("remark", "医药物品，请小心轻放！");
                cargoInfoDtoList.add(cargoInfo);
            }
            billPrinter.put("cargoInfoDtoList", cargoInfoDtoList);

            String routeDes = waybillObj.getRouteDes();
            JSONObject routeObj = JSONObject.parseObject(routeDes);
            if (routeObj == null) {
                return null;
            }
            billPrinter.put("zipCode", waybillObj.getOriginCode());
            billPrinter.put("destCode", waybillObj.getDestCode());
            billPrinter.put("insureValue", null);

            //丰密信息
            JSONArray rlsInfoDtoList = new JSONArray();
            JSONObject rlsInfo = new JSONObject();
            rlsInfo.put("waybillNo", routeObj.getString("waybillNo"));
            rlsInfo.put("abFlag", StringUtils.isBlank(routeObj.getString("abFlag")) ? "" : routeObj.getString("abFlag"));
            rlsInfo.put("xbFlag", StringUtils.isBlank(routeObj.getString("xbFlag")) ? "" : routeObj.getString("xbFlag"));
            rlsInfo.put("proCode", StringUtils.isBlank(routeObj.getString("proCode")) ? "" : routeObj.getString("proCode"));
            rlsInfo.put("destRouteLabel", StringUtils.isBlank(routeObj.getString("destRouteLabel")) ? "" : routeObj.getString("destRouteLabel"));
            rlsInfo.put("destTeamCode", StringUtils.isBlank(routeObj.getString("destTeamCode")) ? "" : routeObj.getString("destTeamCode"));
            rlsInfo.put("codingMapping", StringUtils.isBlank(routeObj.getString("codingMapping")) ? "" : routeObj.getString("codingMapping"));
            rlsInfo.put("codingMappingOut", StringUtils.isBlank(routeObj.getString("codingMappingOut")) ? "" : routeObj.getString("codingMappingOut"));
            rlsInfo.put("sourceTransferCode", StringUtils.isBlank(routeObj.getString("sourceTransferCode")) ? "" : routeObj.getString("sourceTransferCode"));
            rlsInfo.put("printIcon", StringUtils.isBlank(routeObj.getString("printIcon")) ? "" : routeObj.getString("printIcon"));
            rlsInfo.put("qrcode", StringUtils.isBlank(routeObj.getString("twoDimensionCode")) ? "" : routeObj.getString("twoDimensionCode"));
            rlsInfoDtoList.add(rlsInfo);
            billPrinter.put("rlsInfoDtoList", rlsInfoDtoList);

        } catch (Exception e) {
            log.error("丰桥API {下订单接口} Request Params Error = " + e.getMessage());
        } finally {
            log.info("顺丰面单打印实体初始化！ id {} " + order.getNumber());
        }

        return billPrinter;
    }

    /**
     * 下订单接口参数封装
     * @param order
     * @param orderDetails
     * @param waybillObj
     * @return
     */
    public static JSONObject generateWaybillOrder(Order order, List<OrderDetails> orderDetails, Waybill waybillObj) {
        //订单
        JSONObject waybill = new JSONObject();
        try {
            waybill.put("language", language);
            waybill.put("orderId", order.getNumber());//快递单号
            waybill.put("cargoDesc", "医疗药品");//托寄物描述
            waybill.put("monthlyCard", SystemConfig.p.getProperty("sf.monthlyCard"));//顺丰月结卡号
            waybill.put("orderSource", "WECHAT_STORE");//平台编码 微信咨询平台
            waybill.put("remark", waybillObj.getWaybillRemark());//订单备注
            waybill.put("payMethod", payMethod);//寄放付

            //业务需要增加
            //waybill.put("isReturnQRCode", "0");//是否返回用来推送业务的二维码 1:返回 0:不返回
            //waybill.put("specialDeliveryTypeCode", "1");//特殊派送类型代码 1:身份验证
            //waybill.put("specialDeliveryValue", "12345678");//特殊派件具体表述 证件类型:证件后8位如：1:09296231（1 表示身份证,暂不支持其他证件）
            //waybill.put("isReturnSignBackRoutelabel", "0");//是否返回签回单路由标签： 默认0， 1：返回路由标签，0：不返回
            //waybill.put("isReturnRoutelabel", "0");//是否返回路由标签： 默认0， 1：返回路由标签， 0：不返回
            //waybill.put("podModelAddress", "url");//签单返回范本地址

            //特殊需求药品，需冷冻、冷藏
            if (StringUtils.isNoneBlank(waybillObj.getExpressTypeId())) {
                waybill.put("expressTypeId", waybillObj.getExpressTypeId());//快件产品类别Id  12医药类 冷冻 冷藏
                //waybill.put("temperatureRange", waybillObj.getTemperatureRange());//1:冷藏 3：冷冻
            }

            //托寄物信息List
            JSONArray cargoDetails = new JSONArray();
            for (OrderDetails orderd: orderDetails) {
                JSONObject cargo = new JSONObject();
                cargo.put("name", orderd.getProductName());//商品名称
                cargo.put("count", orderd.getDrugsNum());//商品数量
                cargo.put("unit", "盒");//商品单位
                cargo.put("amount", orderd.getPrice());//商品价格
                cargo.put("currency", currencyCode);//币种编码
                cargoDetails.add(cargo);
            }
            waybill.put("cargoDetails", cargoDetails);

            //收寄双方信息List
            JSONArray contactInfoList = new JSONArray();

            //寄件方信息
            JSONObject sender = new JSONObject();
            sender.put("contactType", "1");
            sender.put("company", "扬州诺康大药房有限公司");
            sender.put("contact", "吴赵龙");
            sender.put("tel", "0514-82360278");
            sender.put("mobile", "15150808407");
            sender.put("country", countryCode);
            sender.put("province", "江苏省");
            sender.put("city", "扬州市");
            sender.put("county", "邗江区");
            sender.put("address", "科技园路18号");
            contactInfoList.add(sender);

            //收件方信息
            JSONObject recipient = new JSONObject();
            recipient.put("contactType", "2");
            recipient.put("contact", waybillObj.getContact());
            recipient.put("tel", waybillObj.getMobile());
            recipient.put("mobile", waybillObj.getMobile());
            recipient.put("country", countryCode);
            recipient.put("province", waybillObj.getProvince());
            recipient.put("city", waybillObj.getCity());
            recipient.put("county", waybillObj.getCounty());
            recipient.put("address", waybillObj.getAddress());
            contactInfoList.add(recipient);

            waybill.put("contactInfoList", contactInfoList);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("丰桥API {下订单接口} Request Params Error = " + e.getMessage());
            return null;
        }
        return waybill;
    }

    /**
     * 订单查询接口封装
     * @param searchType 查询类型：1.正向单查询，传入的orderId为正向订单号，2.退货单查询，传入的orderId为退货原始订单号
     * @return
     */
    public static JSONObject generateOrderSel(Order order, String searchType) {
        JSONObject retObj = new JSONObject();
        try {
            retObj.put("orderId", order.getNumber());
            retObj.put("searchType", searchType);
            retObj.put("language", language);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("丰桥API 订单查询接口 Request Params Error = " + e.getMessage());
            return null;
        }
        return retObj;
    }

    /**
     * 订单确认/取消接口
     * @param order
     * @param type
     * @return
     */
    public JSONObject generateOrderCancel(Order order, Waybill waybillObj, String type) {
        JSONObject retObj = new JSONObject();
        try {
            retObj.put("orderId", order.getNumber());
            retObj.put("dealType", type);

            JSONArray waybillNoInfoList = new JSONArray();
            JSONObject waybill = new JSONObject();
            waybill.put("waybillType", 1);//母单
            waybill.put("waybillNo", waybillObj.getWaybillNo());
            waybillNoInfoList.add(waybill);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("丰桥API {订单查询、取消} Request Params Error = " + e.getMessage());
            return null;
        }
        return retObj;
    }

    /**
     * 路由查询
     * @param waybillObj
     * @return
     */
    public static JSONObject generateRouteData(Waybill waybillObj) {
        JSONObject retObj = new JSONObject();
        try {
            retObj.put("language", 0);//中文
            retObj.put("trackingType", 1);//1:根据顺丰运单号查询

            JSONArray waybills = new JSONArray();
            retObj.put("trackingNumber", waybills);//顺丰运单号
            retObj.put("methodType", 1);//标准路由查询
        } catch (Exception e) {
            e.printStackTrace();
            log.error("丰桥API 订单查询接口 Request Params Error = " + e.getMessage());
        }
        return retObj;
    }

    /**
     * 生成顺丰签名
     * @return
     */
    public static String generateSfDigest(String msgData, Long timestamp, String checkWord) {
        String msgDigest = null;
        try {
            StringBuffer verifyText = new StringBuffer();
            verifyText.append(msgData);
            verifyText.append(timestamp);
            verifyText.append(checkWord);

            //String verifyText = msgData + timestamp + checkWord;

            //因业务报文中可能包含加号、空格等特殊字符，需要urlEnCode处理
            String text = URLEncoder.encode(verifyText.toString(), "UTF-8");

            //进行Md5加密
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(text.getBytes("UTF-8"));
            byte[] md = md5.digest();

            //通过BASE64生成数字签名
            msgDigest = new String(new BASE64Encoder().encode(md));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("丰桥API 生成接口签名 md5 base64 error = " + e.getMessage());
            return null;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            log.error("丰桥API 生成接口签名 无算法异常 md5 base64 error = " + e.getMessage());
            return null;
        }
        return msgDigest;
    }

}
