package com.bohuikeji.delivery.backstage.thread;

import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.entity.TOrderCircu;
import com.bohuikeji.delivery.backstage.entity.third.OrderDetailDO;
import com.bohuikeji.delivery.backstage.service.third.JdServer;
import com.bohuikeji.delivery.backstage.service.third.SfCityServer;
import com.bohuikeji.delivery.backstage.service.third.UUServer;
import com.bohuikeji.delivery.backstage.service.third.base.ThirdBase;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.utils.SpringUtil;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;

/**
 * 第三放配送业务处理线程
 * @author 孙劲辉
 */
@Slf4j
public class ThirdThread implements Runnable {
    /**
     * 缓存过期时间为45天
     */
    private static final int DAY_TIME =3600*24*45;

    /**
     * 第三方业务处理对象
     */
    private final ThirdBase third;
    private final TOrder order;
    private final RedisUtil redisUtil= SpringUtil.getBean(RedisUtil.class);

    public ThirdThread(ThirdBase third, TOrder order){
        this.third=third;
        this.order=order;
    }

    /**
     * 执行对三方订单推送线程
     * 【注】每个第三方会开启一个独立线程，互不影响，故此线程支持控制业务休眠、重启等异步操作
     */
    @Override
    public void run() {
        //对已经指定了服务商的订单进行识别，仅推送指定的服务商
        if (StringUtils.isNotBlank(order.getThirdName())){
            if (!this.third.getName().equals(order.getThirdName())){
                log.error("【第三方订单推送取消】该订单:{},已经指定了服务商：{}，当前服务商：{}",order.getOrderNum(),order.getThirdName(),this.third);
                APIEntity<OrderDetailDO> res= APIEntity.fail("【第三方订单推送取消】该订单:{},已经指定了服务商：{}",order.getOrderNum(),order.getThirdName());
                redisUtil.set(this.third.getCacheKey(this.order.getOrderNum()).replaceFirst("third","result"),res,DAY_TIME);
                return;
            }
        }
        //两分钟后再推送UU
        if (UUServer.NAME.equals(this.third.getName())){
            try {
                Thread.sleep(Duration.ofMinutes(2).toMillis());
            } catch (InterruptedException e) {
                log.error("第三方下单线程错误：{}",order);
            }
        }
        for (int i = 0; i < ThirdBase.frans.length; i++) {
            if(SfCityServer.NAME.equals(this.third.getName())){
                if(!order.getFranId().equals(ThirdBase.frans[i])){
                    try {
                        Thread.sleep(Duration.ofSeconds(30).toMillis());
                    } catch (InterruptedException e) {
                        log.error("第三方下单线程错误：{}",order);
                    }
                }else {
                    try {
                        Thread.sleep(Duration.ofMinutes(1).toMillis());
                    } catch (InterruptedException e) {
                        log.error("第三方下单线程错误：{}",order);
                    }
                }
            }
            /*if(order.getFranId().equals(ThirdBase.frans[i]) && SfExpressServer.NAME.equals(this.third.getName())){
                try {
                    Thread.sleep(Duration.ofMinutes(1).toMillis());
                } catch (InterruptedException e) {
                    log.error("第三方下单线程错误：{}",order);
                }
            }*/
        }

        //推送订单，并将推送结果详情写入缓存
        APIEntity<OrderDetailDO> res=this.third.orderInquiryAndPlace(this.order);
        if (res!=null){
            //仅当推送成功放入推送详情缓存，以供第三方回调进入后获取订单信息
            if (res.checkSuccess()){
                OrderDetailDO detail= res.getBody();
                redisUtil.set(this.third.getCacheKey(detail.getOrderNumber()),detail,DAY_TIME);
            }
            //无论成功或者失败都要报告推送结果到缓存
            redisUtil.set(this.third.getCacheKey(this.order.getOrderNum()).replaceFirst("third","result"),res,DAY_TIME);
            //对于京东订单还要存入结果到订单变更记录表，以便客户在APP上可以看到下单失败的原因
            if (JdServer.NAME.equals(third.getName())){
                if ("D".equals(order.getOrderNum().substring(0,1))){
                    TOrderCircu.insertCircu(order.getOrderId(),null,order.getOrderNum(),res.getMessage());
                }
            }
        }
    }
}
