package com.hys.app.service.kuaidiniao;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hys.app.converter.erp.OrderConverter;
import com.hys.app.framework.context.user.AdminUserContext;
import com.hys.app.framework.database.BaseQueryParam;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.framework.util.ScriptUtil;
import com.hys.app.mapper.erp.KdnMapper;
import com.hys.app.mapper.goods.ProductMapper;
import com.hys.app.model.erp.dos.*;
import com.hys.app.model.erp.enums.OrderTypeEnum;
import com.hys.app.model.erp.enums.SaleOrderSendStatusEnum;
import com.hys.app.model.erp.enums.SaleOrderStatusEnum;
import com.hys.app.service.erp.ItemSnCodeManager;
import com.hys.app.service.erp.OrderManager;
import com.hys.app.service.erp.OrderSendManager;
import com.hys.app.service.kuaidiniao.entity.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class KuaiDiNiaoServiceImpl implements KuaiDiNiaoService {


    /**
     * 快递鸟apiId
     */
    @Value("${kuaidianiao.id}")
    private String id;
    /**
     * 快递鸟apiKey
     */
    @Value("${kuaidianiao.key}")
    private String apiKey;

    /**
     * 快递鸟请求地址
     */
    @Value("${kuaidianiao.apiUrl}")
    private String url;


    /**
     * 快递鸟apiId
     */
    @Value("${kuaidianiao.kuaidi.id}")
    private String kuaiDiId;
    /**
     * 快递鸟apiKey
     */
    @Value("${kuaidianiao.kuaidi.key}")
    private String kuaiDiKey;

    /**
     * 快递鸟请求地址
     */
    @Value("${kuaidianiao.kuaidi.apiUrl}")
    private String kuaiDiUrl;

    @Autowired
    private OrderSendManager orderSendManager;

    @Autowired
    private OrderManager orderManager;

    @Autowired
    private OrderConverter converter;

    @Autowired
    private ItemSnCodeManager itemSnCodeManager;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private KdnMapper kdnMapper;


    private static final Logger log = LoggerFactory.getLogger(ScriptUtil.class);


    @Override
    public String kdShip(PreOrderModelDTO preOrderModel, Long orderId, AddressDTO addressDTO) {
        fillParam(preOrderModel);
        String kdnCode = sendUrl(JSONUtil.toJsonStr(preOrderModel));
        if (StrUtil.isNotEmpty(kdnCode)) {
            //如果快递鸟下单成功保存 快递信息
            OrderSendDO aDo = orderSendManager.getById(orderId);
            log.info("快递鸟下单成功 我们的订单号:---------------------" + orderId);
            converter.copyProperties(aDo, preOrderModel, preOrderModel.getReceiver(), preOrderModel.getSender());
            aDo.setGoodsList(preOrderModel.getGoodsList());
            aDo.setKdnOrderCode(kdnCode);
            aDo.setSendAddress(addressDTO.getSendAddress());
            aDo.setReceiveAddress(addressDTO.getReceiveAddress());
            orderSendManager.updateById(aDo);
        }
        return kdnCode;
    }

    @Override
    public void createStore(CreateStoreModel createStoreModel, String constants) {
        Long modelId = createStoreModel.getId();
        createStoreModel.setId(null);
        fillParam(createStoreModel);
        try {
            String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(createStoreModel) + apiKey)), "UTF-8");
            System.out.println("创建店铺签名--------------------------------------" + design);
            //拼接参数
            String param = "interfaceType=" + constants + "&customerCode=" + id + "&requestData=" + JSONUtil.toJsonStr(createStoreModel) + "&dataSign=" + design;
            //发请求
            String res = HttpUtil.post(url, param);
            Map map = JSON.parseObject(res, Map.class);
            if (ObjectUtil.isNotNull(map.get("resultCode")) && !(100 == Integer.parseInt(map.get("resultCode").toString()))) {
                throw new ServiceException("店铺创建失败" + map.get("reason").toString());
            }
            Map dataMap = JSON.parseObject(JSON.toJSONString(map.get("data")), Map.class);
            createStoreModel.setKdnStoreCode(dataMap.get("kdnStoreCode").toString());
            if (ObjectUtil.isNotNull(modelId)) {
                createStoreModel.setId(modelId);
                kdnMapper.updateById(createStoreModel);
            } else {
                kdnMapper.insert(createStoreModel);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("店铺创建异常");
        }
    }

    @Override
    public Page<CreateStoreModel> getStoreList(BaseQueryParam baseQueryParam) {
        return kdnMapper.selectPage(new Page<>(baseQueryParam.getPageNo(), baseQueryParam.getPageSize()), new LambdaQueryWrapper<>());
    }

    @Override
    public void selectAudit(CreateStoreModel createStoreModel) {
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("storeCode", createStoreModel.getStoreCode());
        try {
            String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(hashMap) + apiKey)), "UTF-8");
            System.out.println("获取门店状态签名--------------------------------------" + design);
            //拼接参数
            String param = "interfaceType=" + KdConstants.queryStoreStatus + "&customerCode=" + id + "&requestData=" + JSONUtil.toJsonStr(hashMap) + "&dataSign=" + design;
            //发请求
            String res = HttpUtil.post(url, param);
            Map map = JSON.parseObject(res, Map.class);
            if (ObjectUtil.isNotNull(map.get("resultCode")) && !(100 == Integer.parseInt(map.get("resultCode").toString()))) {
                throw new ServiceException("请求状态失败" + map.get("reason").toString());
            }
            Map dataMap = JSON.parseObject(JSON.toJSONString(map.get("data")), Map.class);
            List<Map> storeDetail = JSON.parseArray(dataMap.get("storeDetail").toString(), Map.class);
            for (Map statusMap : storeDetail) {
                switch (statusMap.get("intraCode").toString()) {
                    case "SS":
                        createStoreModel.setSsStatus(Integer.parseInt(statusMap.get("storeStatus").toString()));
                        createStoreModel.setSsReason(statusMap.get("operationFailReason").toString());
                    case "DD":
                        createStoreModel.setDdStatus(Integer.parseInt(statusMap.get("storeStatus").toString()));
                        createStoreModel.setDdReason(statusMap.get("operationFailReason").toString());
                    case "FN":
                        createStoreModel.setFnStatus(Integer.parseInt(statusMap.get("storeStatus").toString()));
                        createStoreModel.setFnReason(statusMap.get("operationFailReason").toString());
                    case "MTPS":
                        createStoreModel.setMtStatus(Integer.parseInt(statusMap.get("storeStatus").toString()));
                        createStoreModel.setMtReason(statusMap.get("operationFailReason").toString());
                }
            }
            kdnMapper.updateById(createStoreModel);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("请求发生异常");
        }
    }

    /**
     * 订阅就行了，订阅成功与否均不影响货物的正常派发
     */
    @Override
    public void queryLogistics(LogisyicsTopic logisyicsTopic) {
        try {
            String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(logisyicsTopic) + kuaiDiKey)), "UTF-8");
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("RequestData", JSONUtil.toJsonStr(logisyicsTopic));
            paramMap.put("DataType", 2);
            paramMap.put("EBusinessID", kuaiDiId);
            paramMap.put("DataSign", design);
            paramMap.put("RequestType", KdConstants.orderLogistics);
            String res = HttpUtil.post(kuaiDiUrl, paramMap);
            log.info(logisyicsTopic.getLogisticCode() + "快递鸟轨迹订阅" + res);
        } catch (Exception e) {

        }

    }

    @Override
    public Boolean kdnReturnBackLogistics(Map map) {
        try {
            OrderSendDO sendDO = orderSendManager.getOne(new LambdaQueryWrapper<OrderSendDO>().eq(OrderSendDO::getLogisticsCode, map.get("LogisticCode").toString()).last("limit 1"));
            if (ObjectUtil.isNotNull(sendDO)) {
                List<Map> maps = JSON.parseArray(JSON.toJSONString(map.get("Traces")), Map.class);
                sendDO.setLogistics(maps);
            }
            orderSendManager.updateById(sendDO);
            return true;
        }catch (Exception e){
            return false;
        }
    }


    /**
     * @param dataJson 业务参数
     * @return 返回JSON
     */
    private String sendUrl(String dataJson) {
        try {
            String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(dataJson + apiKey)), "UTF-8");
            System.out.println("--------------------------------------" + design);
            //拼接参数
            String param = "interfaceType=" + KdConstants.preOrder + "&customerCode=" + id + "&requestData=" + dataJson + "&dataSign=" + design;
            //发请求
            String res = HttpUtil.post(url, param);
            Map map = JSON.parseObject(res, Map.class);
            //resultCode == 100表示预下单成功，预下单郑工后立马调用下单接口
            if (ObjectUtil.isNotNull(map.get("resultCode")) && 100 == Integer.valueOf(map.get("resultCode").toString())) {
                //拼接参数
                String createParam = "interfaceType=" + KdConstants.createOrder + "&customerCode=" + id + "&requestData=" + dataJson + "&dataSign=" + design;
                //发请求
                String resCreate = HttpUtil.post(url, createParam);
                Map mapCreate = JSON.parseObject(resCreate, Map.class);
                //resultCode == 100表示下单成功，预下单成功后立马调用下单接口
                if (ObjectUtil.isNotNull(mapCreate.get("resultCode")) && 100 == Integer.valueOf(mapCreate.get("resultCode").toString())) {
                    Map mapData = JSON.parseObject(mapCreate.get("data").toString(), Map.class);
                    log.info("快递鸟下单成功 单号：--------------------------------" + mapData.get("kdnOrderCode").toString());
                    return mapData.get("kdnOrderCode").toString();
                }
            } else {
                throw new ServiceException(map.get("reason").toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
//            return "1234567899";
            throw new ServiceException("请求快递鸟发货异常，请联系客服");
        }
        return null;
    }

    private void fillParam(PreOrderModel preOrderModel) {
        //填充送货人的经纬度
        LongitudeLatitude longitudeLatitudeSender = GaoDeUtil.getLongitudeLatitude(preOrderModel.getSender().getProvinceCityAreaAddress());
        preOrderModel.getSender().setLongitude(longitudeLatitudeSender.getLongitude());
        preOrderModel.getSender().setLatitude(longitudeLatitudeSender.getLatitude());
        //填充收货人的经纬度
        LongitudeLatitude longitudeLatitudeReceiver = GaoDeUtil.getLongitudeLatitude(preOrderModel.getSender().getProvinceCityAreaAddress());
        preOrderModel.getReceiver().setLongitude(longitudeLatitudeReceiver.getLongitude());
        preOrderModel.getReceiver().setLatitude(longitudeLatitudeReceiver.getLatitude());
        //获取下单人信息
        preOrderModel.setOrderName(AdminUserContext.getAdminUserName());
        preOrderModel.setOrderPhone("13127911751");

    }

    private void fillParam(CreateStoreModel model) {
        LongitudeLatitude longitudeLatitudeSender = GaoDeUtil.getLongitudeLatitude(model.getProvinceName() + model.getCityName() + model.getAreaName() + model.getAddress());
        model.setLongitude(longitudeLatitudeSender.getLongitude());
        model.setLatitude(longitudeLatitudeSender.getLatitude());
        //填充送货人的经纬度
    }

    /**
     * 推送待接单状态	接口指令103，状态码100
     * 推送业务员接单状态	接口指令103，状态码201
     * 推送业务员到达状态	接口指令103，状态码202
     * 推送配送中状态	接口指令103，状态码300
     * 推送签收状态
     * (签收分为两种签收)	接口指令103，状态码401（正常签收）
     * 接口指令103，状态码402（退回签收）
     * 推送取消状态	接口指令103，状态码500
     * 推送下单失败状态	接口指令103，状态码600
     * 推送订单费用状态	接口指令103，状态码206
     */

    @Override
    public resReturnBackBase kdnReturnBack(ReturnBackInstant returnBackBase) {
        Map map = JSON.parseObject(returnBackBase.getRequestData(), Map.class);
        resReturnBackBase base = new resReturnBackBase();
        base.setKdnOrderCode(map.get("kdnOrderCode").toString());
        //验签
        OrderSendDO aDo = orderSendManager.getById(Long.valueOf(map.get("orderCode").toString()));
        OrderDO orderDO = orderManager.getById(aDo.getOrderId());
        //        if (!checkDesign(aDo, returnBackBase.getDataSign())) {
//            base.setRequestData("验签失败");
//            base.setResultCode(1002);
//            return base;
//        }
        if (ObjectUtil.isNull(aDo)) {
            base.setReason("未找到对应的订单");
            log.error("未找到对应的订单-------------------------------" + map.get("orderCode").toString());
            base.setResultCode(1002);
            return base;
        }

        switch (map.get("orderStatus").toString()) {
            case KdConstants.callBackPreAccept:
                aDo.setCreateOrderSuccess(map);
                break;
            case KdConstants.callBackAccept:
                aDo.setUserTakeOrder(map);
                break;
            case KdConstants.callBackAttain:
                aDo.setUserArrives(map);
                break;
            case KdConstants.callBackSending:
                aDo.setUserSending(map);
                break;
            case KdConstants.callBackSign:
                aDo.setSignIn(map);
                aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SINGE);
                if (OrderTypeEnum.TO_B.equals(orderDO.getType())) {
                    orderDO.setStatus(SaleOrderStatusEnum.ORDER_END);
                }
                if (OrderTypeEnum.TO_C.equals(orderDO.getType())) {
                    orderDO.setStatus(SaleOrderStatusEnum.TO_BE_RETURN);
                }
                break;
            case KdConstants.callBackSignRefuse:
                aDo.setSignIn(map);
                aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SINGE);
                if (OrderTypeEnum.TO_B.equals(orderDO.getType())) {
                    orderDO.setStatus(SaleOrderStatusEnum.ORDER_END);
                }
                if (OrderTypeEnum.TO_C.equals(orderDO.getType())) {
                    orderDO.setStatus(SaleOrderStatusEnum.TO_BE_RETURN);
                }
                break;
            case KdConstants.callBackCancelStatus:
                aDo.setCancelOrderKdn(map);
                break;
            case KdConstants.callBackCreateOrderFail:
                aDo.setCreateOrderFail(map);
                break;
            case KdConstants.callBackFeeStatus:
                aDo.setOrderFee(map);
                break;
            default:
                base.setResultCode(1002);
                base.setReason("内部业务异常,麻烦尽快通知商家,tel:13127911751");
        }
        orderSendManager.updateById(aDo);
        return base;
    }

    private Boolean checkDesign(OrderSendDO aDo, String dataSign) {
        try {
            PreOrderModel model = new PreOrderModel();
            converter.copyProperties(model, aDo);
            model.setGoodsList(aDo.getGoodsList());
            String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(model) + apiKey)), "UTF-8");
            if (dataSign.equals(design)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }


}
