package com.shkj.wms.outbound;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shkj.common.constant.RedisConstant;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.system.service.ISysParameterService;
import com.shkj.wms.bo.BaseBarcodesOutAddBo;
import com.shkj.wms.bo.BaseBarcodesOutQueryBo;
import com.shkj.wms.bo.BaseDeriveQueryBo;
import com.shkj.wms.constants.ParameterConstants;
import com.shkj.wms.domain.BaseBarcodesOut;
import com.shkj.wms.domain.BaseDerive;
import com.shkj.wms.service.*;
import com.shkj.wms.service.impl.BaseLocationServiceImpl;
import com.shkj.wms.service.impl.SysStockDetailServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zjx
 */
@Component
@Slf4j
public class SchedulingOutboundInfo {


    @Autowired
    IBusinBillheadService iBusinBillheadService;
    @Resource
    RedisTemplate redisTemplate;
    @Resource
    IBaseDeriveService iBaseDeriveService;
    @Resource
    IBaseBarcodesOutService iBaseBarcodesOutService;
    @Resource
    SysStockDetailServiceImpl sysStockDetailServiceimpl;

    @Autowired
    BaseLocationServiceImpl baseLocationService;

    @Resource
    IBusinDataTaskService businDataTaskService;

    @Resource
    ISysParameterService isysParameterService;

    /**
     * 每10分钟执行一次出库任务，具体根据业务定；可以配置在任务管理中
     *      已停用
     * @return
     */
//    @Scheduled(fixedDelay = 1*10000)
    public void outboundInfoTask(){
        //查询待生成出库单任务的车辆队列
        BaseBarcodesOutQueryBo bo = new BaseBarcodesOutQueryBo();
        String taskMinutes = isysParameterService.selectConfigByKey(SecurityUtils.getCurrentBranchId(), ParameterConstants.ParameterSystem.taskMinutes);
        bo.setTaskMinutes(taskMinutes);
        List<BaseBarcodesOutAddBo> barcodesOutList = iBaseBarcodesOutService.selectVinOutboundList(bo);
        if (ObjectUtils.isNotEmpty(barcodesOutList)) {
            businDataTaskService.insertBusinTask(barcodesOutList);
        }
    }

    /**
     * 手动下发任务
     * @author Comair
     * @date 2023/7/27 10:08
     */
    @Scheduled(fixedDelay = 1*10000)
    public void outboundInfoTaskByVin(){
        // 判断从 redis 中获取的手动下发任务的开始任务是否有值
        // 有值的话就进行逻辑处理；如果没有就直接跳过
        if(ObjectUtils.isEmpty(redisTemplate.opsForValue().get(RedisConstant.startTaskVin))){
//            log.info("暂未设置生成任务的开始任务");
            return;
        }
        // 将redis 中的值转成字符串
        String vin = redisTemplate.opsForValue().get(RedisConstant.startTaskVin).toString();
        log.info("出库VIN号："+vin);
        // 初始化生产任务集合
        List<BaseBarcodesOutAddBo> barcodesOutList = new ArrayList<>();
        // 根据vin获取对应的出库任务数据——主要是过点时间
        BaseBarcodesOutQueryBo baseBarcodesOutQueryBo = new BaseBarcodesOutQueryBo();
        baseBarcodesOutQueryBo.setVin(vin);
        BaseBarcodesOut baseBarcodesOut = iBaseBarcodesOutService.getOne(new LambdaQueryWrapper<BaseBarcodesOut>().eq(BaseBarcodesOut::getVin,vin).isNull(BaseBarcodesOut::getIs_cancel));
        // 通过过点时间获取等于该时间或者大于过点时间的任务数据  只获取一条数据
        baseBarcodesOutQueryBo = new BaseBarcodesOutQueryBo();
        baseBarcodesOutQueryBo.setTraverseDate(baseBarcodesOut.getTraverseDate());
        BaseBarcodesOutAddBo barcodesOut = iBaseBarcodesOutService.selectVinOutboundListOne(baseBarcodesOutQueryBo);
        // 判断是否有任务，如果没有任务则返回
        barcodesOutList.add(barcodesOut);
        if (ObjectUtils.isEmpty(barcodesOutList)) {
            log.info("暂无任务");
            return;
        }
        // 获取小组装任务最大等待数
        String temp = isysParameterService.selectConfigByKey(SecurityUtils.getCurrentBranchId(), ParameterConstants.ParameterSystem.waitTaskNumber);

        int waitTaskNumber = Integer.parseInt(temp);
        // 获取小组装前后杠目前有多少等待数

        int assemblePointTypeBefore =
                ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(RedisConstant.assemblePointBeforeTaskCount))
                        ? Integer.parseInt(redisTemplate.opsForValue().get(RedisConstant.assemblePointBeforeTaskCount).toString()) : 0;
        log.info("获取小组装任务最大等待数:"+waitTaskNumber+"  获取小组装前后杠目前有多少等待数:"+assemblePointTypeBefore);
        //小组装点位为一个
        int assemblePointTypeAfter =
                ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(RedisConstant.assemblePointAfterTaskCount))
                        ? Integer.parseInt(redisTemplate.opsForValue().get(RedisConstant.assemblePointAfterTaskCount).toString()) : 0;
        // 判断是否小于最大等待数，如果小于则生成任务，如果不小于就直接返回
        if(assemblePointTypeBefore < waitTaskNumber && assemblePointTypeAfter < waitTaskNumber){
//        if(assemblePointTypeBefore < waitTaskNumber){
            // 判断是否已经设置停止任务的vin；
            // 如果有则判断是否已经执行到该任务；如果执行到该任务就直接删除开始任务vin和停止任务vin,意思就是不在执行生成任务；
            // 如果没执行到该停止任务，这不需要理会
            if(ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(RedisConstant.endTaskVin))){
                String endTaskVin = redisTemplate.opsForValue().get(RedisConstant.endTaskVin).toString();
                if(endTaskVin.equals(barcodesOut.getVin())){
                    redisTemplate.delete(RedisConstant.startTaskVin);
                    redisTemplate.delete(RedisConstant.endTaskVin);
                }
            }
            businDataTaskService.insertBusinTask(barcodesOutList);
        }else{
            log.info("已经到达组装线最大等待任务数 "+waitTaskNumber);
        }
    }

    /**
     * 出库任务
     */
 /*
    public void  outboundInfo(){
        //获取出库表中待出库的信息
        List<BaseBarcodesOutVo> baseBarcodesOutVoList = iBaseBarcodesOutService.getBarcodesnoOutData();
        //将所有的产品编码聚合
        List<String> goodsno = baseBarcodesOutVoList.stream().map(e -> e.getGoodsNo()).collect(Collectors.toList());
        //拿到所有的货位信息
        List<SysStockDetailVo> SysStockDetailVoList = sysStockDetailServiceimpl.getLocation(goodsno);
        //拿到分体可以在同一任务出库的产品编码和货位信息
        Map<String, List<String>> locationneaten = sysStockDetailServiceimpl.getLocationneaten(SysStockDetailVoList);
        //将所有的货位信息进行聚合
//        List<Long> locationList = SysStockDetailVoList.stream().map(e -> e.getLocationId()).collect(Collectors.toList());

        for (BaseBarcodesOutVo outVo: baseBarcodesOutVoList) {
            //通过货位拿到巷道信息
            List<BaseLocationVo> tunnelVo = baseLocationService.getTunnel(outVo.getGoodsNo());
            List<String> tunnelall = tunnelVo.stream().map(e -> e.getTunnel()).collect(Collectors.toList());
            //拿到任务数最少的巷道
            String tunnelone=this.quickSort(tunnelall);
            List<BaseLocationVo> tunnelLocation = tunnelVo.stream().filter(e -> e.getTunnel().equals(tunnelone)).collect(Collectors.toList());
            //根据巷道分配货位
            BaseLocationVo baseLocationVo = tunnelLocation.get(0);

            //修改出库表状态为进行中并添加任务
            BusinDataTask businDataTask = new BusinDataTask();
            //回填任务相关数据
            businDataTask.setBatch(outVo.getBatch());
            businDataTask.setToColumn(String.valueOf(baseLocationVo.getHeight()));
            businDataTask.setToLayer(baseLocationVo.getLocationColumn());
            businDataTask.setToRow(baseLocationVo.getLocationRow());
            //添加巷道任务数和总任务数
            TunnelTaskUtil.getInstance().addOutboundTaskNum(baseLocationVo.getTunnel());
            TunnelTaskUtil.getInstance().getOutboundTaskNum(baseLocationVo.getTunnel());
            iBusinDataTaskService.save(businDataTask);
        }





    }*/


}
