package com.ruoyi.wms.service;

import com.alibaba.fastjson.JSONObject;
import com.cmeim.common.core.exception.ServiceException;
import com.cmeim.common.core.utils.DateUtil;
import com.cmeim.common.core.web.domain.RespondEnum;
import com.ruoyi.wms.enums.AgvTaskEnum;
import com.ruoyi.wms.enums.RequestEnum;
import com.ruoyi.wms.repository.AgvTaskRepository;
import com.ruoyi.wms.repository.AreaConfigRepository;
import com.ruoyi.wms.repository.OrderInfoRepository;
import com.ruoyi.wms.repository.ShelfInfoRepository;
import com.ruoyi.wms.repository.StationInfoRepository;
import com.ruoyi.wms.repository.StoreInfoRepository;
import com.ruoyi.wms.po.AgvTask;
import com.ruoyi.wms.po.AreaConfig;
import com.ruoyi.wms.po.ContainerInfo;
import com.ruoyi.wms.po.OrderInfo;
import com.ruoyi.wms.po.ShelfInfo;
import com.ruoyi.wms.po.StationInfo;
import com.ruoyi.wms.po.StoreInfo;
import com.ruoyi.wms.repository.ContainerInfoRepository;
import com.ruoyi.wms.vo.AgvRequestVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @Verasion:1.0
 * @Author:DZY
 * @Date:2023/6/30
 **/
@Service
@Slf4j
public class ScheduleService {
    @Autowired
    private StationInfoRepository stationInfoRepository;
    @Autowired
    private AgvTaskRepository agvTaskRepository;
    @Autowired
    private ContainerInfoRepository containerInfoRepository;
    @Autowired
    private ContainerService containerService;
    @Autowired
    private AGVService agvService;
    @Autowired
    private StoreInfoRepository storeInfoRepository;
    @Autowired
    private OrderInfoRepository orderInfoRepository;
    @Autowired
    private ShelfInfoRepository shelfInfoRepository;
    @Autowired
    private AreaConfigRepository areaConfigRepository;

    /**
     * 出库工位任务
     */
    public void waterTest() {
        //查询出库工位状态
        final List<StationInfo> stationInfos = stationInfoRepository.findByStationTypeAndStationStatus(10, 10);
        stationInfos.forEach(e -> {
            //判断AGV任务列表是否存在该类型并正在进行中的任务
            AtomicReference<Boolean> flag = new AtomicReference<>(true);
            List<AgvTask> agvTasks = new ArrayList<>();
            agvTasks = agvTaskRepository.findByDictTypeAndStatus(RequestEnum.OUTSTORE.getCode(), AgvTaskEnum.ONGOING.getCode());
            if (agvTasks.size() > 0) {
                agvTasks.forEach(m -> {
                    //取未完成任务目标工作位的值,如果和当前工作为一致，则不新建任务。
                    JSONObject jsonObject = JSONObject.parseObject(m.getJson());
                    String taskDescribe = jsonObject.getString("taskDescribe");
                    final String toLocationCode = JSONObject.parseObject(taskDescribe).getString("toStationCode");
                    if (toLocationCode.equals(e.getStationCode())) {
                        flag.set(false);
                    }
                });
            } else {
                waterRequestParam(e.getStationCode(), e.getProductionTask());
                return;
            }
            if (flag.get() && null != agvTasks) {
                waterRequestParam(e.getStationCode(), e.getProductionTask());
            }
        });
    }

    /**
     * @param stationCode 工位编码
     * @param number    任务单号
     */
    public void waterRequestParam(String stationCode, String number) {
        //得到可以出库的箱子列表
        final List<ContainerInfo> containerInfos = containerService.queryGreaterThanEightHours();
        final List<ContainerInfo> collect = containerInfos.stream().filter(e -> e.getProductionTask().equals(number)).collect(Collectors.toList());
        Integer boxNumber = 4;
        //判断请求空箱数量是否大约仓库空箱数量
        if (collect.size() < 4) {
            boxNumber = collect.size();
        }
        List<ContainerInfo> sendContainer = new ArrayList<>();
        JSONObject data = new JSONObject(true);
        //搬运方式
        data.put("taskType", "carry");
        //任务组优先级
        data.put("groupPriority", 0);
        List<JSONObject> taskList = new ArrayList<>();
        for (int i = 0; i < boxNumber; i++) {
            UUID uuid = UUID.randomUUID();
            String taskCode = uuid.toString();
            ContainerInfo containerInfo = collect.get(i);
            JSONObject data1 = new JSONObject(true);
            //任务单号
            data1.put("taskCode", taskCode);
            //任务优先级
            data1.put("taskPriority", 2);
            JSONObject data2 = new JSONObject(true);
            //容器编码
            data2.put("containerCode", containerInfo.getContainerNumber());
            //容器类型
            data2.put("containerType", "CT_KUBOT_STANDARD");
            //工作位标签
            final AreaConfig areaConfig = areaConfigRepository.findByAreaType(RequestEnum.SENDWAITCHECK.getCode());
            if (null != areaConfig) {
                data2.put("storageTag", areaConfig.getAreaCode());
            } else {
                data2.put("storageTag", "");
            }
            //起始工作位
            data2.put("fromLocationCode", "");
            //目标工作位
            data2.put("toLocationCode", "");
            //目标工作站
            data2.put("toStationCode", stationCode);
            data1.put("taskDescribe", data2);
            taskList.add(data1);
            sendContainer.add(containerInfo);
        }
        if (taskList.size() == 0) {
            return;
        }
        data.put("tasks", taskList);
        log.info("料箱出库param:" + JSONObject.toJSONString(data));
        final String result = agvService.taskCreate(JSONObject.toJSONString(data), RequestEnum.OUTSTORE.getCode());
        log.info("料箱出库result:" + result);
        int code = JSONObject.parseObject(result).getInteger("code");
        //请求发送成功
        if (code == 0) {
            OrderInfo orderInfo = orderInfoRepository.findByProductionTask(number);
            sendContainer.forEach(e -> {
                //修改为出库中状态
                e.setContainerStatus(35);
                containerInfoRepository.save(e);
                //修改库位状态,待空闲
                StoreInfo storeInfo = storeInfoRepository.findByStoreCode(e.getStoreCode());
                if (storeInfo != null) {
                    storeInfo.setStoreStatus(20);
                    storeInfoRepository.save(storeInfo);
                }
                //修改单据出库数据
                if (orderInfo != null) {
                    if (orderInfo.getOnoutingCheckQty() == null) {
                        orderInfo.setOnoutingCheckQty(0);
                    }
                    orderInfo.setOnoutingCheckQty(orderInfo.getOnoutingCheckQty() + e.getQty());
                    //orderInfo.setInQty(orderInfo.getInQty() - e.getQty());
                }
            });
            orderInfo.setUpdatedDt(DateUtil.getCurrentDate());
            orderInfoRepository.save(orderInfo);
        } else {
            throw new ServiceException(RespondEnum.FAILURE, "任务发起失败");
        }
    }


    /**
     * 送检验工位定时任务
     */
    public void sendCheck() {
        //查询检验工位状态
        final List<StationInfo> stationInfos = stationInfoRepository.findByStationTypeAndStationStatus(15, 10);
        stationInfos.forEach(e -> {
            //判断AGV任务列表是否存在该类型并正在进行中的任务
            AtomicReference<Boolean> flag = new AtomicReference<>(true);
            final List<AgvTask> agvTasks = agvTaskRepository.findByDictTypeAndStatus(RequestEnum.SENDCHECK.getCode(), AgvTaskEnum.ONGOING.getCode());
            if (null != agvTasks) {
                agvTasks.forEach(m -> {
                    //取未完成任务目标工作位的值,如果和当前工作为一致，则不新建任务。
                    final String toLocationCode = JSONObject.parseObject(m.getJson()).getString("toLocationCode");
                    if (toLocationCode.equals(e.getStationCode())) {
                        flag.set(false);
                    }
                });
            } else {
                sendCheckParam(e.getStoreCode(), e.getProductionTask());
            }
            if (flag.get() && null != agvTasks) {
                sendCheckParam(e.getStoreCode(), e.getProductionTask());
            }
        });
    }

    /**
     * 送检验参数
     *
     * @param storeCode 检验工位地码
     * @param number    任务单
     */
    public void sendCheckParam(String storeCode, String number) {
        //查询任务单待检货架
        final List<ShelfInfo> shelfInfos = shelfInfoRepository.findByProductionTaskAndOrderStatus(number, 5);
        if (shelfInfos.size() == 0) {
            return;
        }
        final StoreInfo storeInfo = storeInfoRepository.findByStoreCode(storeCode);
        //判断站位是否空闲，如果不是空闲状态结束任务
        if (storeInfo.getStoreStatus() != 5) {
            return;
        }
        ShelfInfo shelfInfo = shelfInfos.get(0);
        JSONObject data = new JSONObject(true);
        //搬运方式
        data.put("taskType", "carry");
        //任务组优先级
        data.put("groupPriority", 0);
        List<JSONObject> taskList = new ArrayList<>();

        UUID uuid = UUID.randomUUID();
        String taskCode = uuid.toString();
        JSONObject data1 = new JSONObject(true);
        //任务单号
        data1.put("taskCode", taskCode);
        //任务优先级
        data1.put("taskPriority", 0);
        JSONObject data2 = new JSONObject(true);
        //容器编码
        data2.put("containerCode", shelfInfo.getShelfCode());
        //容器类型
        data2.put("containerType", "CT_KUBOT_STANDARD");
        //工作为标签
        data2.put("storageTag", "");
        //起始工作位
        data2.put("fromLocationCode", "");
        //目标工作位
        data2.put("toLocationCode", storeCode);
        //目标工作站
        data2.put("toStationCode", "");
        data1.put("taskDescribe", data2);
        taskList.add(data1);
        data.put("tasks", taskList);
        final String result = agvService.taskCreate(JSONObject.toJSONString(data), RequestEnum.OUTSTORE.getCode());
        int code = JSONObject.parseObject(result).getInteger("code");
        //请求发送成功
        if (code == 0) {
            OrderInfo orderInfo = orderInfoRepository.findByProductionTask(number);
            //修改为出库中状态
            shelfInfo.setOrderStatus(10);
            shelfInfoRepository.save(shelfInfo);
            //修改单据出库数据
            orderInfo.setWaitCheckQty(orderInfo.getWaitCheckQty() - shelfInfo.getQty());
            orderInfo.setCheckQty(orderInfo.getCheckQty() + shelfInfo.getQty());
            orderInfo.setUpdatedDt(DateUtil.getCurrentDate());
            orderInfoRepository.save(orderInfo);
        } else {
            throw new ServiceException(RespondEnum.FAILURE, "任务发起失败");
        }
    }

    /**
     * 待检区已检验货架送抽检定时任务
     */
    public void sendPostCheck() {
        //查询已完成检验送回待检区的货架
        final List<ShelfInfo> shelfInfos = shelfInfoRepository.findByOrderStatus(15);
        //如果没有待检货架，结束任务
        if (shelfInfos.size() == 0) {
            return;
        }
        final List<StoreInfo> storeInfos = storeInfoRepository.findByStoreTypeAndStoreStatus(20, 5);
        //如果没有空闲站位，结束任务
        if (storeInfos.size() == 0) {
            return;
        }
        AgvRequestVo agvRequestVo = new AgvRequestVo();
        agvRequestVo.setType(0);
        agvRequestVo.setToLocationCode(storeInfos.get(0).getStoreCode());
        agvRequestVo.setContainerCode(shelfInfos.get(0).getShelfCode());
        agvRequestVo.setRequestType(RequestEnum.SENDSPOTCHECK.getCode());
        agvService.taskParamCreate(agvRequestVo);
    }


}
