package com.prolog.eis.service.stationOutbound.impl;

import com.prolog.eis.dto.eis4.*;
import com.prolog.eis.service.stationOutbound.StationObCacheDispatchService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Version: 1.0
 * @Author: wuhan
 * @Created: 2024/7/23 17:08
 */
@Service
@RequiredArgsConstructor
public class StationObCacheDispatchServiceImpl implements StationObCacheDispatchService {
    @Override
    public List<StationOBCarryTaskDto> dispatch(StationOBDispatchDto dispatchDto) {
        List<StationOBCarryTaskDto> obCarryTaskList = new ArrayList<>();

        for (StationOBAreaDto area : dispatchDto.getAreaList()) {
            for (int i = area.getContainerList().size() - 1; i > -1; i--) {
                StationOBAreaContainerDto container = area.getContainerList().get(i);
                StationOBContainerDto taskContainer = dispatchDto.findTaskContainer(container.getContainerNo());
                if (taskContainer == null) {
                    continue;
                }

                if (!container.isFinishTask()) {
                    continue;
                }

                if (this.checkWait(dispatchDto, area)) {
                    continue;
                }

                StationOBAreaDto cacheArea = this.findBestCacheAreaNo(dispatchDto, taskContainer);
                if (cacheArea != null && cacheArea != area) {
                    cacheArea.increaseUseLocatorCount();
                    dispatchDto.removeContainer(taskContainer.getContainerNo());

                    StationOBCarryTaskDto carryTaskDto = new StationOBCarryTaskDto();
                    carryTaskDto.setContainerNo(container.getContainerNo());
                    carryTaskDto.setSourceAreaNo(container.getAreaNo());
                    carryTaskDto.setTargetAreaNo(cacheArea.getAreaNo());

                    obCarryTaskList.add(carryTaskDto);
                }
            }
        }

        return obCarryTaskList;
    }

    /**
     * 检查该区域有任务托盘是否可以原地等待
     *
     * @return
     */
    private boolean checkWait(StationOBDispatchDto dispatchDto, StationOBAreaDto area) {
        //检查是否开启了原地等待
        if (!area.isCanWait()) {
            return false;
        }

        if (dispatchDto.getCarryTaskWillArriveAreaNoHs().contains(area.getAreaNo())) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 从该容器的所有任务区域找出第一次有空闲位的缓存区
     *
     * @param dispatchDto
     * @param taskContainer
     * @return
     */
    private StationOBAreaDto findBestCacheAreaNo(StationOBDispatchDto dispatchDto, StationOBContainerDto taskContainer) {
        for (StationOBContainerTaskDto task : taskContainer.getContainerTaskList()) {
            for (String taskTargetAreaNo : task.getTaskTargetAreaNoList()) {
                StationOBAreaDto taskTargetArea = dispatchDto.findArea(taskTargetAreaNo);
                if (taskTargetArea == null) {
                    continue;
                }

                for (String cacheAreaNo : taskTargetArea.getCacheAreaNoList()) {
                    StationOBAreaDto cacheArea = dispatchDto.findArea(cacheAreaNo);
                    if (cacheArea == null) {
                        continue;
                    }

                    if (cacheArea.getFreeLocatorCount() > 0) {
                        return cacheArea;
                    }
                }
            }
        }

        return null;
    }
}
