package com.bohuikeji.delivery.backstage.listener.order;

import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.entity.third.OrderDetailDO;
import com.bohuikeji.delivery.backstage.service.IGmsService;
import com.bohuikeji.delivery.backstage.service.ITOrderArrearsService;
import com.bohuikeji.delivery.backstage.service.ITOrderService;
import com.bohuikeji.delivery.backstage.service.third.JdServer;
import com.bohuikeji.delivery.backstage.service.third.SfExpressServer;
import com.bohuikeji.frame.module.admin.base.MqListener;
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.ShortUrlVo;
import com.bohuikeji.frame.module.admin.utils.UrlUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 京东订单价格复核线程
 * @author sjh
 * @date 2022/2/24 16:13
 **/
@Service
@Slf4j
@RequiredArgsConstructor
public class JdOrderCheckPriceListener extends MqListener<String> {
    final JdServer jdServer;
    final SfExpressServer sfServer;
    final ITOrderService orderService;
    final IGmsService gmsService;
    final MqTool mqTool;
    final ITOrderArrearsService arrearsService;
    /**
     * 京东补充支付页面H5真实地址(直接访问无效)
     */
    private static final String URL_SUPPLY="http://supply.h5.tcjskd.com";
    /**
     * 京东补充支付页面H5短链接域名
     */
    private static final String URL_BASE_SHORT="https://su.tcjskd.com/";
    /**
     * 接收到消息会调用此方法
     *
     * @param orderNum 消息体
     * @return 【保留返回值】暂无实际用途，后续可能用于支持消息失败重试
     */
    @Override
    public boolean onReceive(String orderNum) {
        TOrder order=orderService.getByNum(orderNum);
        if ("已取消".equals(order.getOrderStatus())) {
            log.error("该订单已经退款或取消，订单:{}",orderNum);
            return true;
        }
        BigDecimal price=null;
        if (SfExpressServer.NAME.equals(order.getThirdName())){
            APIEntity<OrderDetailDO> sfRes=sfServer.orderDetail(orderNum,order.getThirdNum());
            if (sfRes.checkSuccess()){
                price=sfRes.getBody().getOrderPrice().subtract(order.getOrderFactPrice().add(order.getPrefAmount()));
            }
        }else {
            price=jdServer.computeSupplyPay(orderNum);
        }
        if (price==null) {
            log.error("【快递订单复核】订单：{}，价格正在核算中,三分钟后再试......",orderNum);
            //没有计费结果，延迟3分钟再查
            mqTool.sendDelayMsg(orderNum, JdOrderCheckPriceListener.class, Duration.ofMinutes(3));
            return true;
        }
        //已经补付完成或者不需要补付，直接结束
        if (price.compareTo(new BigDecimal("1.00"))<0){
            log.error("【快递订单复核】订单：{}，已经补付完成了!",orderNum);
            return true;
        }
        //京东价格比订单价格高，说明存在差价，发送短信
        ShortUrlVo vo=ShortUrlVo.init(URL_SUPPLY,true);
        //修改真实地址添加参数
        vo.setRealUrl(URL_SUPPLY+"?k="+vo.getShortUrlPrefix());
        vo.setData(orderNum);
        //生成短链接，有效期2小时，放入订单号为元数据
        String sortUlr=URL_BASE_SHORT+ UrlUtils.createShortUrl(vo,Duration.ofDays(30).getSeconds(),true);
        String phone=orderService.getCustomerPhone(orderNum);
        //发送支付提示短信
        gmsService.sendOrderSupply(phone,orderNum,price,sortUlr);
        //获取从确认取件到现在的时间差
        Duration duration=Duration.between(orderService.getByNum(orderNum).getConfirmPickTime(), LocalDateTime.now());
        //第二天中午再催一次,超时前2小时再发一次即将超时通知
        if(duration.toMinutes()<=20){
            mqTool.sendDelayMsg(orderNum, JdOrderCheckPriceListener.class, LocalDate.now().plusDays(1).atTime(12,10));
            mqTool.sendDelayMsg(orderNum, OrderPayTimeOutListener.class, Duration.ofHours(46));
        }
        arrearsService.insertRecord(orderNum,phone,"SMS_ORDER_SUPPLY_H5",price,sortUlr);
        return true;
    }

    /**
     * 当消费者业务代码出现异常时会调用该方法
     *
     * @param msg 消息体
     * @param e   异常信息
     */
    @Override
    public void onError(String msg, Exception e) {

    }
}
