package com.clx.performance.strategy;

import com.clx.order.enums.VehicleUsageEnum;
import com.clx.performance.param.pc.OrderGoodsChildParams;
import com.clx.performance.param.pc.OrderGoodsParams;
import com.clx.order.enums.OrderStopEnum;
import com.clx.order.enums.ResultEnum;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dao.OrderGoodsTruckBindDao;
import com.clx.performance.model.OrderGoodsTruckBind;
import com.clx.performance.utils.SpringContextUtils;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public abstract class GoodsOrderStrategy {

    @Autowired
    private Environment environment;


    /**
     * 不同的用车需求执行不同的策略   1：one  2:two 3:three
     * 用车需求： 1平台车辆 2部分平台车辆 3自有车辆
     *
     * @param orderGoodsParams
     * @param orderInfo
     * @param now
     * @return
     */
    public abstract LocalDateTime goodsOrderProcess(OrderGoodsParams orderGoodsParams, FeignOrderVO orderInfo, LocalDateTime now);


    public void saveGoodsOrder(OrderGoodsParams orderGoodsParams, FeignOrderVO orderInfo, LocalDateTime now, RabbitTemplate rabbitTemplate) {
        String orderNo = orderGoodsParams.getOrderNo();
        if (Objects.equals(orderInfo.getStopFlag(), OrderStopEnum.Status.YES.getCode())) {
            throw new ServiceSystemException(ResultEnum.DATA_ERROR, "订单已暂停，无法进行提量");
        }
        String transportBeginTime = orderInfo.getTransportBeginTime();
/*        if (!"test".equals(environment.getActiveProfiles()[0])) {
            for (OrderGoodsChildParams param : orderGoodsParams.getOrderGoodsChildParams()) {
                String pendingOrderTime = param.getPendingOrderTime();
                if (DateUtils.parseDateTime(pendingOrderTime).get().isBefore(DateUtils.parseDateTime(transportBeginTime).get())) {
                    throw new ServiceSystemException(ResultEnum.DATA_ERROR, "挂单时间不能早于拉运开始时间");
                }
            }
        }*/

        //多个定向单不允许车辆重复
        List<OrderGoodsChildParams> orderGoodsChildParams = orderGoodsParams.getOrderGoodsChildParams();
        Set<String> set = new HashSet<>();
        for (OrderGoodsChildParams item : orderGoodsChildParams) {
            //定向车自由车辆不做拦截操作
            if (!StringUtils.equals(item.getVehicleUsage(),String.valueOf(VehicleUsageEnum.Status.OWN.getCode())) && CollectionUtils.isNotEmpty(item.getTruckList())) {
                int lastSize = set.size() + item.getTruckList().size();
                set.addAll(item.getTruckList());
                if (!Objects.equals(lastSize, set.size())) {
                    throw new ServiceSystemException(ResultEnum.DATA_ERROR, "定向单选择车辆重复");
                }
            }
        }

        if (CollectionUtils.isNotEmpty(set)) {
            OrderGoodsTruckBindDao orderGoodsTruckBindDao = SpringContextUtils.getBeanByClass(OrderGoodsTruckBindDao.class);
            List<OrderGoodsTruckBind> binds = orderGoodsTruckBindDao.judgeTruckIsBindDxOrder(set);
            if (CollectionUtils.isNotEmpty(binds)) {
                List<String> repeatBind = binds.stream().map(OrderGoodsTruckBind::getTruckNo).collect(Collectors.toList());
                String trucks = String.join(", ", repeatBind);
                throw new ServiceSystemException(ResultEnum.DATA_ERROR, "已被定向单绑定车辆：" + trucks);            }
        }
        //根据不同的订单类型创建不同的货单
        LocalDateTime sendLazyTime = goodsOrderProcess(orderGoodsParams, orderInfo, now);

        Message message = MessageBuilder.withBody(orderNo.getBytes()).build();
        BigDecimal epochMilli = null;
        if (sendLazyTime.isAfter(now)) {
            epochMilli = new BigDecimal(sendLazyTime.minusMinutes(now.getMinute()).getMinute() * 60 * 1000);
            log.info("执行订单状态更改,选择时间在当前时间之后，则设置延迟队列时间,时间为：{}", epochMilli);

        }
        if (epochMilli == null) {
            log.info("执行订单状态更改,epochMilli时间为0,时间为：{}", epochMilli);

            rabbitTemplate.send(
                    RabbitKeyConstants.ORDER_ON_DEAD_EXCHANGE, RabbitKeyConstants.ORDER_ON_DEAD_ROUTE_KEY, message
            );
        } else {
            log.info("执行订单状态更改,epochMilli时间不为0,时间为：{}", epochMilli);
            rabbitTemplate.send(RabbitKeyConstants.ORDER_POSTED_EXCHANGE, RabbitKeyConstants.ORDER_POSTED_ROUTE_KEY, MessageBuilder.withBody(orderNo.getBytes()).build());

            message.getMessageProperties().setHeader("x-delay", epochMilli);

            rabbitTemplate.send(
                    RabbitKeyConstants.ORDER_ON_EXCHANGE, RabbitKeyConstants.ORDER_ON_ROUTE_KEY, message
            );
        }
    }
}
