package com.bohuikeji.delivery.backstage.service.third.base;

import com.alibaba.fastjson.JSONObject;
import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.entity.TOrderCircu;
import com.bohuikeji.delivery.backstage.entity.open.vo.CourierVo;
import com.bohuikeji.delivery.backstage.entity.third.OrderDetailDO;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 第三方配送服务工厂父类
 * @author 孙劲辉
 */
@Slf4j
public abstract class ThirdBase {

    /**
     * 子类注册
     */
    private static Map<String,Class<?extends ThirdBase>> registers=new HashMap<>();

    /**
     * 订单回调状态注册
     */
    private static Map<String,Map<String,String>> noticeStatus=new HashMap<>();

    /**
     * 子类名称
     */
    protected final String name;

    /**
     * 不推送第三方的加盟地区
     */
    public static Integer[] frans={18,362};

    /**
     * 获取已注册的服务类
     * @return
     */
    public static Map<String,Class<?extends ThirdBase>> getRegisters(){
        return registers;
    }

    /**
     * 获取注册状态信息
     * @return
     */
    public static Map<String,String> getNoticeStatus(String name){return noticeStatus.get(name);}

    /**
     * 获取缓存的KEY
     * @param orderNum
     * @param thirdName
     * @return
     */
    public static String getCacheKey(String orderNum,String thirdName){
        return getCacheKeyPix(orderNum)+thirdName;
    }

    /**
     * 获取前缀
     * @param orderNum
     * @return
     */
    public static String getCacheKeyPix(String orderNum){
        return "order:"+orderNum+":third:";
    }

    /**
     * 获取缓存的KEY
     * @param orderNum 订单号
     * @return
     */
    public String getCacheKey(String orderNum){
        return getCacheKey(orderNum,name);
    }

    /**
     * 获取子类名称
     * @return
     */
    public String getName(){
        return this.name;
    }

    /**
     * 子类向父类注册自己
     * @param name 服务商名称
     * @param cls 服务类
     * @param wait 待接单状态值
     * @param accept 取件中状态值
     * @param run 配送中状态值
     * @param end 已完成状态值
     * @param cancel 已取消状态值
     */
    public ThirdBase(String name, Class<? extends ThirdBase> cls,String wait,String accept,String run,String end,String cancel){
        registers.put(name,cls);
        this.name=name;
        Map<String,String> statusMap=new HashMap<>();
        statusMap.put(wait,"wait");
        statusMap.put(accept,"accept");
        statusMap.put(run,"run");
        statusMap.put(end,"end");
        statusMap.put(cancel,"cancel");
        noticeStatus.put(name,statusMap);
    }

    /**
     * 是否继续推送第三方
     * 判断订单是否符合推送系统条件
     * @param order
     * @return
     */
    protected boolean isContinue(TOrder order){
        //寄付订单不推送
        if(!"寄付".equals(order.getPaymentType())){
            return false;
        }
        if (!"待接单".equals(order.getOrderStatus())){
            return false;
        }
        if(order.getCourierId()!=null){
            return false;
        }
        //京东订单不推送
        if ("D".equals(order.getOrderNum().substring(0,1))){
            return false;
        }
        //客户设置不推送第三方
        if (order.getPlayerId().equals(181420)){
            return false;
        }
        //判断不需要推送第三方的加盟商
        /*for (int i = 0; i < frans.length; i++) {
            if(order.getFranId().equals(frans[i])){
                return  false;
            }
        }*/
        return true;
    }

    /**
     * 计算价格是否满足推送要求
     * @param orderPrice 订单价格
     * @param thirdPrice 第三方价格
     * @return
     */
    protected boolean isPush(BigDecimal orderPrice,BigDecimal thirdPrice){
        //如果预估金额比他高直接推送
        if(orderPrice.compareTo(thirdPrice)>-1){
            return true;
        }
        //第三方差价
        BigDecimal subPrice=thirdPrice.subtract(orderPrice);
        //2元以内的插件直接推送
        if(new BigDecimal("2.00").compareTo(subPrice)>-1){
            return true;
        }
        //差价5元内。且订单金额是25元以上的直接推送
        if(new BigDecimal("5").compareTo(subPrice)>-1){
            if (new BigDecimal("20").compareTo(orderPrice)<1){
                return true;
            }
        }
        //差价10元内,且订单金额是50元以上的直接推送
        if(new BigDecimal("10").compareTo(subPrice)>-1){
            if (new BigDecimal("50").compareTo(orderPrice)<1){
                return true;
            }
        }
        //差价20元内,且订单金额是80元以上的直接推送
        if(new BigDecimal("20").compareTo(subPrice)>-1){
            if (new BigDecimal("80").compareTo(orderPrice)<1){
                return true;
            }
        }
        //差价大于10元。且订单金额是120元以上的直接推送
        if(new BigDecimal("20").compareTo(subPrice)<1){
            if (new BigDecimal("120").compareTo(orderPrice)<1){
                return true;
            }
        }
        //其他情况不推送
        return false;
    }

    /**
     * 询价并下单，子类各自实现业务逻辑
     * 【注意】编写该方法时，下单成功务必再次查询数据库并判断订单状态，如发生变更及时取消
     * @param order 订单
     * @return
     */
     abstract public APIEntity<OrderDetailDO> orderInquiryAndPlace(TOrder order);

    /**
     * 获取订单详情
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
     abstract public APIEntity<OrderDetailDO> orderDetail(String orderNum,String thirdNum);

    /**
     * 获取订单详情
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
    abstract public APIEntity<CourierVo> courierInfo(String orderNum, String thirdNum);

    /**
     * 取消订单
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
    abstract public APIEntity<JSONObject> orderCancel(String orderNum,String thirdNum);

    /**
     * 取消订单
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
    abstract public APIEntity<JSONObject> orderTip(String orderNum,String thirdNum,BigDecimal tipAmount);

    /**
     * 获取第三方的订单流转记录
     * @param orderNum 订单号
     * @param thirdNum 三方单号
     * @return 第三方没有此类接口返回null或者size=0
     */
    abstract public List<TOrderCircu> orderRecord(String orderNum,String thirdNum);

    /**
     * 使用状态码计算文本描述
     * @param statusCode
     * @return
     */
    abstract public String queryStatusDesc(int statusCode);

    /**
     * 订单复核，骑手取件成功后调用，向第三方平台复核订单信息是否有变化，可用于地址修改同步，价格差价补付等
     * @param orderNum 订单号
     * @param thirdNum 第三方订单号
     */
    abstract public void orderReview(String orderNum,String thirdNum);


}
