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

import com.alibaba.fastjson.JSONArray;
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.delivery.backstage.listener.order.OrderCheckPriceListener;
import com.bohuikeji.delivery.backstage.service.ITOrderService;
import com.bohuikeji.delivery.backstage.service.third.base.ThirdBase;
import com.bohuikeji.delivery.backstage.util.capacity.SfExpressUtils;
import com.bohuikeji.frame.module.admin.component.MqTool;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 顺丰快递服务类
 * @author Admin
 */
@Slf4j
@Component
public class SfExpressServer extends ThirdBase {

    final MqTool mqTool;
    final ITOrderService orderService;

    /**
     * 子类向父类注册自己
     *
     */
    public SfExpressServer(MqTool mqTool,ITOrderService orderService) {
        super(NAME,SfExpressServer.class, "0", "110", "130", "200", "900");
        this.mqTool=mqTool;
        this.orderService=orderService;
    }

    /**
     * 服务名
     */
    public static final String NAME ="SFKD";

    /**
     * 询价并下单，子类各自实现业务逻辑
     * 【注意】编写该方法时，下单成功务必再次查询数据库并判断订单状态，如发生变更及时取消
     *
     * @param order 订单
     * @return
     */
    @Override
    public APIEntity<OrderDetailDO> orderInquiryAndPlace(TOrder order) {
        log.error("##################################顺丰快递下单业务#######################");
        //return APIEntity.fail("由于顺丰月结业务调整中，暂停推送订单！");

        if (!JdServer.isJdOrder(order.getOrderNum())){
            return APIEntity.fail("【顺丰订单推送取消】订单：{}，非顺丰订单。",order.getOrderNum());
        }
        //获取计费信息
        JSONObject res=SfExpressUtils.orderEstimate(order);
        if (res==null){
            return APIEntity.fail("【顺丰订单计费错误】详见计费日志");
        }
        String[] sendTime=res.getString("deliverTime").split(",");
        BigDecimal price=res.getBigDecimal("price");
        JSONObject orderRes=SfExpressUtils.placeOrder(order);
        if (orderRes==null){
            return APIEntity.fail("【顺丰下单失败】。");
        }
        if (orderRes.getIntValue("httpStatus")!=200){
            return APIEntity.fail(orderRes.getString("message"));
        }
        OrderDetailDO detailDO=new OrderDetailDO();
        detailDO.setThirdName(NAME);
        detailDO.setThirdNum(orderRes.getJSONObject("data").getString("mailNumber"));
        detailDO.setOrderNumber(order.getOrderNum());
        detailDO.setDistance(String.valueOf(order.getOrderDistance()));
        detailDO.setOrderPrice(price);
        detailDO.setEstimateTime(sendTime[0]+"至"+sendTime[1]);
        order.setThirdName(NAME);
        order.setThirdNum(orderRes.getJSONObject("data").getString("mailNumber"));
        orderService.updateById(order);
        //1分钟后复核下单结果
        //mqTool.sendDelayMsg(detailDO, SfOrderPlaceCheck.class,Duration.ofSeconds(5));
        return APIEntity.success(detailDO);
    }

    /**
     * 获取订单详情
     *
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
    @Override
    public APIEntity<OrderDetailDO> orderDetail(String orderNum, String thirdNum) {
        JSONObject res=SfExpressUtils.orderDetail(orderNum,thirdNum);
        if (res==null){
            log.error("顺丰查询订单详情失败，返回null，订单号：{},三方单号：{}",orderNum,thirdNum);
            return APIEntity.fail("未找到订单费用信息，可能尚未取件！");
        }
        OrderDetailDO detailDO=new OrderDetailDO();
        detailDO.setOrderNumber(res.getString("orderId"));
        detailDO.setThirdNum(res.getString("waybillNo"));
        detailDO.setThirdName(this.name);
        JSONArray fees=res.getJSONArray("fees");
        BigDecimal price=new BigDecimal("0");
        for (int i = 0; i < fees.size(); i++) {
            price=price.add(fees.getJSONObject(i).getBigDecimal("value"));
        }
        detailDO.setOrderPrice(price);
        return APIEntity.success(detailDO);
    }

    @Override
    public APIEntity<CourierVo> courierInfo(String orderNum, String thirdNum) {
        return null;
    }

    /**
     * 取消订单
     *
     * @param orderNum 系统订单号
     * @param thirdNum 第三方订单号
     * @return
     */
    @Override
    public APIEntity<JSONObject> orderCancel(String orderNum, String thirdNum) {
        log.error("##################################顺丰快递取消业务#######################");
        JSONObject res=SfExpressUtils.cancelOrder(orderNum,thirdNum);
        log.info("##################################顺丰快递取消业务返回信息：{}",res);
        if (res!=null){
            if (res.getIntValue("resStatus")==2){
                return APIEntity.success();
            }
            return APIEntity.fail("客户订单号与顺丰运单不匹配");
        }
        return APIEntity.fail("顺丰取消订单失败");
    }

    @Override
    public APIEntity<JSONObject> orderTip(String orderNum, String thirdNum, BigDecimal tipAmount) {
        return null;
    }

    /**
     * 获取第三方的订单流转记录
     *
     * @param orderNum 订单号
     * @param thirdNum 三方单号
     * @return 第三方没有此类接口返回null或者size=0
     */
    @Override
    public List<TOrderCircu> orderRecord(String orderNum, String thirdNum) {
        JSONArray res=SfExpressUtils.orderRecord(orderNum,thirdNum);
        if (res==null){
            return null;
        }
        return res.stream().map(item->{
            TOrderCircu circ=new TOrderCircu();
            JSONObject json=(JSONObject) item;
            /*queryStatusDesc(json.getIntValue("opCode"))*/
            circ.setChangeStatus(json.getString("remark"));
            circ.setChangeTime(LocalDateTime.ofInstant(json.getDate("acceptTime").toInstant(), ZoneId.systemDefault()));
            //circ.setChangeDesc(json.getString("remark"));
            return circ;

        }).collect(Collectors.toList());

    }

    /**
     * 使用状态码计算文本描述
     *
     * @param statusCode
     * @return
     */
    @Override
    public String queryStatusDesc(int statusCode) {
        switch (statusCode){
            case 50:
            case 54:
            case 51:
                return "已收件";
            case 21:
            case 204:
            case 125:
            case 46:
            case 43:
            case 41:
            case 30:
            case 31:
                return "运输中";
            case 34:
            case 44:
            case 99:
            case 123:
            case 630:
            case 634:
            case 642:
            case 643:
            case 658:
            case 663:
            case 880:
                return "派送中";
            case 80:
            case 8000:
                return "已签收";
            default:return "异常件";
        }
    }

    /**
     * 订单复核，骑手取件成功后调用，向第三方平台复核订单信息是否有变化，可用于地址修改同步，价格差价补付等
     *
     * @param orderNum 订单号
     * @param thirdNum 第三方订单号
     */
    @Override
    public void orderReview(String orderNum, String thirdNum) {
        //延迟8分钟，复核订单
        //mqTool.sendDelayMsg(orderNum, OrderCheckPriceListener.class, Duration.ofMinutes(8));
    }
}