package com.clx.performance.service.impl.linewarn;

import com.clx.order.vo.feign.FeignOrderInfoVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.linewarn.LineWarnConfigDao;
import com.clx.performance.dao.linewarn.LineWarnInfoDao;
import com.clx.performance.dto.linewarn.LineWarnCommonInfoDTO;
import com.clx.performance.dto.linewarn.LineWarnOrderChildStatisticsDTO;
import com.clx.performance.enums.OrderEnum;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.linewarn.LineWarnConfigEnum;
import com.clx.performance.enums.linewarn.LineWarnInfoEnum;
import com.clx.performance.extranal.user.OrderService;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.linewarn.LineWarnConfig;
import com.clx.performance.model.linewarn.LineWarnInfo;
import com.clx.performance.service.linewarn.LineWarnCommonService;
import com.clx.performance.service.linewarn.LineWarnTakeWarnService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class LineWarnTakeWarnServiceImpl implements LineWarnTakeWarnService {
    // 默认时间
    private static final int DEFAULT_TIME = 60;
    private static final BigDecimal OVER_WEIGHT = new BigDecimal(50);
    private static final BigDecimal STANDARD_WEIGHT = new BigDecimal(35);
    @Autowired
    private LineWarnConfigDao lineWarnConfigDao;
    @Autowired
    private LineWarnInfoDao lineWarnInfoDao;
    @Autowired
    private LineWarnCommonService lineWarnCommonService;
    @Autowired
    private OrderChildDao orderChildDao;
    @Autowired
    private OrderService orderService;

    @Override
    public void takeWarn(OrderGoods orderGoods, LineWarnCommonInfoDTO lineWarnCommonInfo) {

        int loadTimeAvg = lineWarnCommonInfo.getLoadTimeAvg();
        int unloadTimeAvg = lineWarnCommonInfo.getUnloadTimeAvg();
        Integer arriveReceiveExpectTime = lineWarnCommonInfo.getArriveReceiveExpectTime();

        long totalTime = Duration.between(lineWarnCommonInfo.getPendingOrderTime(),
                lineWarnCommonInfo.getTransportEndTime()).toMinutes();
        int needTime = DEFAULT_TIME+loadTimeAvg+unloadTimeAvg+arriveReceiveExpectTime;
        // 接单最长时间
        long difTime = totalTime - needTime;
        if (difTime < 0){difTime = 0;}

        // 任务量
        BigDecimal taskWeight = lineWarnCommonInfo.getTaskWeight();

        // 任务完成率
        BigDecimal taskCompleteRatio = BigDecimal.ZERO;

        FeignOrderInfoVO orderInfo = orderService.getOrderInfo(orderGoods.getOrderNo()).orElseThrow(PerformanceResultEnum.ORDER_INVALID);
        BigDecimal weight = orderChildDao.sumTakeWeightByOrderGoodsNo(orderGoods.getOrderGoodsNo(),
                Objects.equals(orderInfo.getOverWeight(), OrderEnum.OverWeight.YES.getCode())
                        ? OVER_WEIGHT
                        : STANDARD_WEIGHT
        );
        if (weight == null) {weight = BigDecimal.ZERO;}

        taskCompleteRatio = weight.divide(taskWeight, 4, RoundingMode.UP).movePointRight(2);

        log.info("接单预警，任务量:{}, 完成量:{}, 任务完成率:{}, 总时间:{}, 需要时间:{}, 相差时间:{}", taskWeight, weight, taskCompleteRatio, totalTime, needTime, difTime);
        List<LineWarnConfig> lineWarnConfigList = lineWarnConfigDao
                .listByWarnType(LineWarnConfigEnum.WarnType.TAKE.getCode());
        if (lineWarnConfigList.isEmpty()) {return;}

        for (LineWarnConfig item : lineWarnConfigList) {
            doTakeWarn(orderGoods, item,lineWarnCommonInfo.getPendingOrderTime(), difTime, taskCompleteRatio);
        }

    }

    private void doTakeWarn(OrderGoods orderGoods, LineWarnConfig lineWarnConfig, LocalDateTime pendingOrderTime,
                            long difTime, BigDecimal taskCompleteRatio){
        LineWarnInfo lineWarnInfo = lineWarnInfoDao
                .findByOrderGoodsNoAndWarnConfigId(orderGoods.getOrderGoodsNo(), lineWarnConfig.getId()).orNull();
        if (lineWarnInfo != null
                && Objects.equals(lineWarnInfo.getStatus(), LineWarnInfoEnum.Status.RESOLVE.getCode())){
            return;
        }

        // 暂停检测
        boolean suspend = lineWarnCommonService.suspendCheck(lineWarnInfo);
        if (suspend) {return;}

        int time = lineWarnConfig.getTimeRatio().multiply(new BigDecimal(difTime)).movePointLeft(2).intValue();

        // 未达到时间占比
        if (pendingOrderTime.plusMinutes(time).isAfter(LocalDateTime.now())){return;}
        // 达到任务占比
        if (lineWarnConfig.getTaskCompleteRatio().compareTo(taskCompleteRatio) < 0) {return;}

        // 更新
        lineWarnCommonService.lineWarnInfoUpdate(orderGoods, lineWarnInfo, lineWarnConfig);

    }

}

