package com.huaheng.api.acs.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaheng.api.acs.domain.AgvPort;
import com.huaheng.api.acs.domain.AgvTaskCS;
import com.huaheng.api.acs.domain.ToAgvTask;
import com.huaheng.api.acs.mapper.AgvTaskCsMapper;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.support.Convert;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.http.HttpUtils;
import com.huaheng.common.utils.http.OkHttpUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.framework.web.domain.AjaxResultWCS;
import com.huaheng.framework.web.service.ConfigService;
import com.huaheng.pc.config.address.service.AddressService;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.containerType.domain.ContainerType;
import com.huaheng.pc.config.containerType.service.ContainerTypeService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.station.domain.Station;
import com.huaheng.pc.config.station.service.StationService;
import com.huaheng.pc.task.taskHeader.domain.TaskHeader;
import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
import javafx.concurrent.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class AgvTaskCSServiceImpl extends ServiceImpl<AgvTaskCsMapper, AgvTaskCS> implements AgvTaskCSService {
    @Resource
    private AgvPortService agvPortService;
    @Resource
    private ContainerService containerService;
    @Resource
    private ConfigService configService;
    @Resource
    private AddressService addressService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private LocationService locationService;
    @Resource
    private ContainerTypeService containerTypeService;
    @Resource
    private StationService stationService;

    @Override
    public AjaxResult createAGVTask(AgvTaskCS agvTask) {
        if (StringUtils.isNull(agvTask.getPreTaskNo())) {
            //校验请求参数
            checkAgvTaskPosition(agvTask);
            //校验托盘是否存在任务及是否锁定
            checkContainerAndPositionStatus(agvTask);
            //校验自己生成的任务中源点位的托盘和实际托盘一不一致
            checkContainerAndPositionLove(agvTask);
        }
        agvTask.setStatus(QuantityConstant.TASK_STATUS_BUILD);
        agvTask.setCreatedBy(ShiroUtils.getLoginName());
        agvTask.setTaskType(QuantityConstant.STATUS_TASK_CARRY);
        agvTask.setCreatedTime(new Date());
        agvTask.setUpdated(new Date());
        agvTask.setUpdatedBy(ShiroUtils.getLoginName());
        agvTask.setWarehouseCode("CS0001");
        if (save(agvTask)) {
            agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_LOCK);
        } else {
            throw new ServiceException("AGV创建任务失败");
        }
        return AjaxResult.success("执行生成任务成功");
    }
    @Override
    public AjaxResult createAGVTaskJLK(AgvTaskCS agvTask) {

        if (StringUtils.isEmpty(agvTask.getFromPort())) {
            throw new ServiceException("起点为空");
        }
        if (StringUtils.isEmpty(agvTask.getToPort())) {
            throw new ServiceException("终点为空");
        }
        if (StringUtils.isEmpty(agvTask.getContainerCode())) {
            throw new ServiceException("容器为空");
        }
        if (agvTask.getFromPort().equals(agvTask.getToPort())) {
            throw new ServiceException("起点终点不能相同");
        }
        String warehouseCode = ShiroUtils.getWarehouseCode();
        Station station=stationService.getStaionByCode(agvTask.getFromPort(),warehouseCode);
        if(station==null){
            throw new ServiceException("起点不存在");
        }
        Station station1=stationService.getStaionByCode(agvTask.getToPort(),warehouseCode);
        if(station1==null){
            throw new ServiceException("起点不存在");
        }
        if(station.getStationType().equals(station1.getStationType())){
            throw new ServiceException("AGV任务不能工位到工位或同一区域");
        }
        Container container=containerService.getContainerByCode(agvTask.getContainerCode(),warehouseCode);
        if(container==null){
            throw new ServiceException("托盘不存在");
        }
        agvTask.setZoneCode(container.getZoneCode());
        agvTask.setNumber("2");

        agvTask.setStatus(QuantityConstant.TASK_STATUS_BUILD);
        agvTask.setCreatedBy(ShiroUtils.getLoginName());
        agvTask.setTaskType(QuantityConstant.STATUS_TASK_CARRY);
        agvTask.setCreatedTime(new Date());
        agvTask.setUpdated(new Date());
        agvTask.setUpdatedBy(ShiroUtils.getLoginName());
        agvTask.setWarehouseCode(warehouseCode);
        if (save(agvTask)) {
        } else {
            throw new ServiceException("AGV创建任务失败");
        }
        return AjaxResult.success("执行生成任务成功");
    }
    /**
     *             自动下发不下发agv库地面站台的入库任务;手动则不受限制
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult excuteAgvContainer(String containerCode) {
        //查找出库任务,未完成任务的agv任务
        LambdaQueryWrapper<AgvTaskCS> agvTaskLambdaQueryWrapper = new LambdaQueryWrapper();
        agvTaskLambdaQueryWrapper.eq(AgvTaskCS::getContainerCode, containerCode)
                .eq(AgvTaskCS::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .isNotNull(AgvTaskCS::getFromPort)
                .isNotNull(AgvTaskCS::getToPort)
                .eq(AgvTaskCS::getTaskType,QuantityConstant.AGV_TYPE_TAKE)
                .lt(AgvTaskCS::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        agvTaskLambdaQueryWrapper.last("limit 1");
        AgvTaskCS agvTaskCS = getOne(agvTaskLambdaQueryWrapper);
        if(agvTaskCS!=null){
            if(agvTaskCS.getStatus()>1){
                return AjaxResult.success("任务已下发");
            }else{
                return sendTaskToAGV(Convert.toIntArray(agvTaskCS.getId().toString()),false);
            }
        }else{
            return AjaxResult.success("找不到该托盘的入库任务");
        }
    }
    /**
     * @param agvTaskIds
     * @param flag flag为true是自动下发;flag为flase为手动下发
     *             自动下发不下发agv库地面站台的入库任务;手动则不受限制
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult sendTaskToAGV(Integer[] agvTaskIds,boolean flag) {
        AjaxResult result = null;
        boolean finished = false;
        AgvTaskCS task = null;
        Integer taskId=agvTaskIds[0];
        task = getById(taskId);

        if (task.getStatus() >= QuantityConstant.TASK_STATUS_RELEASE) {
            return  AjaxResult.error("任务" + taskId + "已经下发,请不要重复下发,操作中止");
        }
        if (StringUtils.isEmpty(task.getToPort())) {
            return AjaxResult.error("任务没有目标点位,不允许下发");
        }
        if(StringUtils.isNotNull(task.getPreTaskNo())){
            AgvTaskCS agvTaskCS=getById(task.getPreTaskNo());
            if(agvTaskCS!=null&&agvTaskCS.getStatus()!=100){
                //当前置任务未完成,则不下发agv任务
                return  AjaxResult.error("出库任务未完成,还不能下发agv任务");
            }
        }
        //为1时,地面站台不自动回库;演示用
        String value= configService.getKey("AUTO_AGV_BACK",task.getWarehouseCode());
        if(StringUtils.isNotEmpty(value)&&value.equals("1")){
            //agv库,地面站台分拣任务的入库任务,手动状态下发任务;自动状态下不下发
            if (task.getWarehouseCode().equals(QuantityConstant.WAREHOUSE_CS)&&task.getZoneCode().equals("V")) {
                if(task.getTaskType().equals(QuantityConstant.AGV_TYPE_TAKE)&&!task.getFromPort().equals(QuantityConstant.AGV_PORT_CS)){
                    return AjaxResult.error("agv入库任务不自动下发,需手动点击agv页面执行");
                }
            }
        }
        LambdaQueryWrapper<AgvTaskCS> agvTaskLambdaQueryWrapper = new LambdaQueryWrapper();
        agvTaskLambdaQueryWrapper.eq(AgvTaskCS::getToPort, task.getToPort())
                .eq(AgvTaskCS::getWarehouseCode, task.getWarehouseCode())
                .ge(AgvTaskCS::getStatus, QuantityConstant.TASK_STATUS_RELEASE)
                .lt(AgvTaskCS::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        List<AgvTaskCS> list = list(agvTaskLambdaQueryWrapper);
        if (list != null && list.size() > 0) {
            return  AjaxResult.error("目标点位存在任务,请更换目标点位");
        }
        if(StringUtils.isNotNull(task.getTaskHeaderId())){
            LambdaQueryWrapper<TaskHeader> wrapper = new LambdaQueryWrapper();
            wrapper .gt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_RELEASE)
            .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED)
                    .eq(TaskHeader::getZoneCode, task.getZoneCode())
                    .eq(TaskHeader::getWarehouseCode, task.getWarehouseCode())
                    .ne(TaskHeader::getId, task.getTaskHeaderId())
                    .eq(TaskHeader::getPort, task.getToPort());
            List<TaskHeader> list1 = taskHeaderService.list(wrapper);
            if (list1 != null && list1.size() > 0) {
                return  AjaxResult.error("目标点位存在任务,请更换目标点位");
            }
        }


        // 给AGV传递任务
        AjaxResult ajaxResult = agvTaskAssign(task);
        if (ajaxResult==null){
            return AjaxResult.error("下发失败");
        }
        if (ajaxResult != null && ajaxResult.hasErr()) {
            return AjaxResult.error(ajaxResult.getMsg());
        }
        //修改任务头表
        task.setId(taskId);
        task.setStatus(QuantityConstant.TASK_STATUS_RELEASE);
        task.setUpdated(new Date());
        task.setUpdatedBy(ShiroUtils.getLoginName());
        saveOrUpdate(task);

        if(StringUtils.isNotNull(task.getTaskHeaderId())){
            LambdaQueryWrapper<TaskHeader> wrapper = new LambdaQueryWrapper();
            wrapper.eq(TaskHeader::getId,task.getTaskHeaderId());
            wrapper.ne(TaskHeader::getStatus,QuantityConstant.TASK_STATUS_COMPLETED);
            TaskHeader taskHeader=new TaskHeader();
            taskHeader.setStatus(QuantityConstant.TASK_STATUS_RUNNING);

            taskHeaderService.update(taskHeader,wrapper);
        }

        return AjaxResult.success("执行下发任务成功", task);
    }

    @Transactional(rollbackFor = Exception.class)
    public AjaxResult agvTaskAssign(AgvTaskCS agvTask) {
        //1、判断agvHeader是否为空
        if (agvTask == null) {
            return AjaxResult.error("Agv任务为空");
        }
        //2、判断必填字段是否满足
        if (agvTask.getId() == null) {
            return AjaxResult.error("Agv任务号Id为空");
        }
        if (agvTask.getTaskType() == null) {
            return AjaxResult.error("Agv任务类型为空");
        }
        String containerCode = agvTask.getContainerCode();
        if (StringUtils.isEmpty(containerCode)) {
            return AjaxResult.error("Agv任务中容器为空");
        }
        String warehouseCode = agvTask.getWarehouseCode();
        //3、转换实体,初始化Agv任务实体
        ToAgvTask toAgvTask = new ToAgvTask();
        toAgvTask.setTaskNo(String.valueOf(agvTask.getId()));
        toAgvTask.setTaskType(agvTask.getTaskType());
        toAgvTask.setTaskHeaderType(agvTask.getTaskHeaderType());
        toAgvTask.setContainerCode(agvTask.getContainerCode());
        toAgvTask.setFromPort(agvTask.getFromPort());
        toAgvTask.setToPort(agvTask.getToPort());
        toAgvTask.setPriority(100);
        //agv发送任务地址
        String numbers="1";
        if(StringUtils.isNotEmpty(agvTask.getNumber())){
            numbers=agvTask.getNumber();
        }
        //4、发送数据
        return sendDataToAgv(1, warehouseCode, numbers, toAgvTask);
    }

    @Override
    public AjaxResult cancelAGVTask(Integer[] agvTaskIds) {
        for (int taskId : agvTaskIds) {
            AgvTaskCS agvTask = getById(taskId);
            if (agvTask == null) {
                return AjaxResult.error("任务" + taskId + "未找到,操作中止");
            }
            if (agvTask.getStatus() >=QuantityConstant.TASK_STATUS_RELEASE) {
                return AjaxResult.error("存在任务" + agvTask.getId() + "已下发或执行,操作中止");
            }
//            int preTaskNo = taskId;
            if(StringUtils.isNotNull(agvTask.getPreTaskNo())){
                AgvTaskCS agvTaskPre = this.getById(agvTask.getPreTaskNo());
                if(agvTaskPre!=null){
                    return AjaxResult.error("AGV前置任务还存在,不能删除");
                }
            }
//            LambdaQueryWrapper<AgvTaskCS> agvLambdaQueryWrapper = Wrappers.lambdaQuery();
//            agvLambdaQueryWrapper.eq(AgvTaskCS::getPreTaskNo, preTaskNo);
//            AgvTaskCS agvTaskHeader = getOne(agvLambdaQueryWrapper);
//            if (agvTaskHeader != null) {
//                return AjaxResult.error("取消任务失败, 有前置任务" + agvTask.getId());
//            }
            if(StringUtils.isNotNull(agvTask.getTaskHeaderId())){
                TaskHeader taskHeader=taskHeaderService.getById(agvTask.getTaskHeaderId());
                if(taskHeader!=null&&agvTask.getTaskType()!=200){
                    //删除主任务
                    String ids=agvTask.getTaskHeaderId().toString();
                    taskHeaderService.cancelTask(Convert.toIntArray(ids));
                }
            }
            //查出任务明细
            //删除子任务
            //删除主任务
            removeById(taskId);
            //盘点取消任务,恢复明细状态为1
            int taskType = agvTask.getTaskType().intValue();
            cancelPositionStatus(agvTask);
            cancelContainerStatus(agvTask);
        }
        return AjaxResult.success("取消任务成功!");
    }

    @Override
    public AjaxResult cancelTask(Integer id, String warehouseCode, String area) {
        //1、判断参数是否为空
        if (id == null) {
            throw new ServiceException("任务号为空");
        }
        HashMap<String, Object> map = new HashMap();
        List<Integer> list = new ArrayList<>();
        list.add(id);
        map.put("taskNo", list);
        //2、发送数据
        return sendDataToAgv(2, warehouseCode, area, map);
    }

    @Override
    public AjaxResult notifyAGVTask(Map map) {
        AgvTaskCS agvTask = new AgvTaskCS();
        if (map.isEmpty()) {
            return AjaxResult.error("请求数据为空");
        }
        Object o1 = map.get("taskNo");
        Object o2 = map.get("carNo");
        Object o3 = map.get("status");
        if (StringUtils.isNull(o1)) {
            return AjaxResult.error("任务号为空");
        }
        Integer taskNo = Integer.valueOf(o1.toString());
        List<AgvTaskCS> list = list(new LambdaQueryWrapper<AgvTaskCS>().eq(AgvTaskCS::getId, taskNo));
        if (CollectionUtils.isNotEmpty(list)) {
            AgvTaskCS agvTask1 = list.get(0);
            if (agvTask1.getStatus().equals(100)) {
                return AjaxResult.success("任务已经是完成了的");
            }
        } else {
            return AjaxResult.success("任务不存在");
        }
        if (StringUtils.isNotNull(o2)) {
            String carNo = o2.toString();
            agvTask.setCarNo(carNo);
        }
        if (StringUtils.isNull(o3)) {
            return AjaxResult.error("任务状态为空");
        }
        Integer status = Integer.valueOf(o3.toString());
        agvTask.setId(taskNo);
        agvTaskStatusNowStart(status, agvTask);
        return AjaxResult.success();
    }

    /**
     * 将参数传输给AGV
     *
     * @param
     * @param warehouseCode
     * @param area
     * @param object
     * @return
     */
    private AjaxResult sendDataToAgv(int i, String warehouseCode, String area, Object object) {
        String value = configService.getKey(QuantityConstant.RULE_CONNECT_AGV,warehouseCode);
        int connectAGV = Integer.parseInt(value);
        String url = null;
        if (connectAGV == QuantityConstant.RULE_AGV_CONNECT) {
            if (i == 1) {
                url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN, warehouseCode, area);
            } else if (i == 2) {
                url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_CANCEL, warehouseCode, area);
            } else {

            }
            String JsonParam = JSON.toJSONString(object);
            System.out.println(JsonParam);
            String result = OkHttpUtils.bodypost(url, JsonParam, warehouseCode);
            if (result == null) {
                return AjaxResult.error("调用失败:接口地址连接失败");
            } else {
                AjaxResultWCS ajaxResultWCS = JSON.parseObject(result, AjaxResultWCS.class);
                if (ajaxResultWCS.hasErr()) {
                    return AjaxResult.error(ajaxResultWCS.getMessage());
                }
                return AjaxResult.success(ajaxResultWCS.getMessage());
            }
        }
        return AjaxResult.success("下发成功");
    }

    //根据agv的任务状态来判断
    private AjaxResult agvTaskStatusNowStart(Integer o3, AgvTaskCS agvTask) {
        AgvTaskCS task = getById(agvTask.getId());
        if (task == null) {
            return AjaxResult.error("任务号" + agvTask.getId() + "不存在");
        }
        if (task.getStatus()==QuantityConstant.TASK_STATUS_COMPLETED) {
            return AjaxResult.error("任务" + agvTask.getId() + "已经完成");
        }
        if (o3.equals(QuantityConstant.STATUS_TASK_AGV_START)) {
            agvTask.setStatus(20);
            task.setUpdated(new Date());
            updateById(agvTask);
        }
        if (o3.equals(QuantityConstant.STATUS_TASK_AGV_TASKOVER)) {
            agvTask.setStatus(50);
            task.setUpdated(new Date());
            updateById(agvTask);
        }
        if (o3.equals(QuantityConstant.STATUS_TASK_FINISH)) {
            task.setStatus(100);
            task.setUpdated(new Date());
            updateById(task);
            agvPortService.updateStatus(task.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY);
            return AjaxResult.success();
        }
        return AjaxResult.success();
    }

    //根据任务类型检验参数
    private void checkAgvTaskPosition(AgvTaskCS agvTask) {
        if (StringUtils.isNull(agvTask)) {
            throw new ServiceException("任务数据为空,请重新下发");
        }
        if (StringUtils.isEmpty(agvTask.getContainerCode())) {
            throw new ServiceException("托盘为空");
        }

        AgvPort sourcePosition = agvPortService.getAgvportByCode(agvTask.getFromPort());
        AgvPort desPosition = agvPortService.getAgvportByCode(agvTask.getToPort());

        if (StringUtils.isEmpty(agvTask.getFromPort())) {
            throw new ServiceException("源点位为空");
        }
        if (StringUtils.isNull(sourcePosition)) {
            throw new ServiceException("源点位:" + sourcePosition.getName() + "未找到");
        }
//        if(sourcePosition.getStatus().equals(QuantityConstant.STATUS_POSITION_LOCK)){
//            throw new ServiceException("源点位:" + sourcePosition.getName() + "禁用");
//        }

        if (StringUtils.isEmpty(agvTask.getToPort())) {
            throw new ServiceException("目标点位为空");
        }
        if (StringUtils.isNull(desPosition)) {
            throw new ServiceException("目标点位:" + desPosition.getName() + "未找到");
        }
        if (!desPosition.getUserDef1()) {
            return;
        }
        if (desPosition.getStatus().equals(QuantityConstant.STATUS_POSITION_LOCK)) {
            throw new ServiceException("目标点位:" + desPosition.getName() + "禁用");
        }
//        if (StringUtils.isNotEmpty(desPosition.getContainerCode())) {
//            throw new ServiceException("目标点位:" + desPosition.getName() + "存在托盘:" + desPosition.getContainerCode());
//        }
        if (QuantityConstant.STATUS_CONTAINER_FULL.equals(desPosition.getStatus())) {
            throw new ServiceException("目标点位:" + desPosition.getName() + "已满");
        }

    }


    /**
     * 检查托盘和点位是否存在未完成的任务
     *
     * @param agvTask
     */
    private void checkContainerAndPositionStatus(AgvTaskCS agvTask) {

        TaskHeader containerLKTaskStatus = taskHeaderService.getOne(new LambdaQueryWrapper<TaskHeader>()
                .eq(TaskHeader::getContainerCode, agvTask.getContainerCode())
                .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED));
        AgvTaskCS containerAgvTaskStatus = getOne(new LambdaQueryWrapper<AgvTaskCS>()
                .eq(AgvTaskCS::getContainerCode, agvTask.getContainerCode())
                .lt(AgvTaskCS::getStatus, QuantityConstant.TASK_STATUS_COMPLETED));
        if (StringUtils.isNotNull(containerLKTaskStatus) || StringUtils.isNotNull(containerAgvTaskStatus)) {
            throw new ServiceException("托盘" + agvTask.getContainerCode() + "存在未完成的任务");
        }

        Container containerStatus = containerService.getContainerByCode(agvTask.getContainerCode(),"CS0001");
        if (StringUtils.isNull(containerStatus)) {
            throw new ServiceException("托盘" + agvTask.getContainerCode() + "不存在");
        }
        if (QuantityConstant.STATUS_CONTAINER_LOCK.equals(containerStatus.getStatus())) {
            throw new ServiceException("托盘" + agvTask.getContainerCode() + "已锁定");
        }

        AgvPort pointPosition = agvPortService.getOne(new LambdaQueryWrapper<AgvPort>()
                .eq(AgvPort::getContainerCode, agvTask.getContainerCode())
                .eq(AgvPort::getStatus, QuantityConstant.STATUS_CONTAINER_LOCK)
                .orderByAsc(AgvPort::getType).last("limit 1"));
        if (pointPosition != null) {
            throw new ServiceException("点位" + pointPosition.getCode() + "已锁定,托盘在此位置不能生成任务");
        }
    }

    //校验自己生成的任务中源点位的托盘和实际托盘一不一致
    @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
    private void checkContainerAndPositionLove(AgvTaskCS agvTask) {
        AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getFromPort());
        if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) {
            if (!agvTask.getContainerCode().equals(agvPort.getContainerCode())) {
                throw new ServiceException("源点位上托盘数据和分配的托盘不一致,请核对");
            }
        }

    }

    //更新点位状态
    @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
    private void cancelPositionStatus(AgvTaskCS agvTask) {
        if (agvTask.getFromPort() != null) {
            //更新点位状态
            AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getFromPort());
            if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) {
                agvPortService.updateStatus(agvTask.getFromPort(), QuantityConstant.STATUS_POSITION_EMPTY);
            } else {
                agvPortService.updateStatus(agvTask.getFromPort(), QuantityConstant.STATUS_POSITION_EMPTY);
            }
        }
        if (agvTask.getToPort() != null) {
            //更新点位状态
            AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getToPort());
            if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) {
                agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY);
            } else {
                agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY);

            }
        }

    }

    //更新容器状态
    @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
    private void cancelContainerStatus(AgvTaskCS agvTask) {
        Container container = new Container();
        container.setStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
        LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate();
        containerUpdateWrapper.eq(Container::getCode, agvTask.getContainerCode());
        containerService.update(container, containerUpdateWrapper);
    }
    @Override
    public AgvTaskCS getAgvTaskByHeaderId(TaskHeader taskHeader,Integer taskType){
        LambdaQueryWrapper<AgvTaskCS> lambda = com.huaheng.common.utils.Wrappers.lambdaQuery();
        lambda.eq(AgvTaskCS::getTaskHeaderId, taskHeader.getId())
                .eq(AgvTaskCS::getWarehouseCode,taskHeader.getWarehouseCode())
                .eq(AgvTaskCS::getTaskType,taskType)
                .orderByDesc(AgvTaskCS::getId).last("Limit 1");
        return this.getOne(lambda);
    }
    public AgvTaskCS getAgvTaskByTaskHeaderId(TaskHeader taskHeader,Integer taskType){
        LambdaQueryWrapper<AgvTaskCS> lambda = com.huaheng.common.utils.Wrappers.lambdaQuery();
        lambda.eq(AgvTaskCS::getTaskHeaderId, taskHeader.getId())
                .eq(AgvTaskCS::getWarehouseCode,taskHeader.getWarehouseCode())
                .lt(AgvTaskCS::getStatus,100)
                .orderByDesc(AgvTaskCS::getId).last("Limit 1");
        return this.getOne(lambda);
    }

    /**
     * 第1段任务
     * @param taskHeader
     * @return
     */
    @Override
    public AgvTaskCS saveAGVTaskByTask(TaskHeader taskHeader) {

        AgvTaskCS agvTask = new AgvTaskCS();
        agvTask.setWarehouseCode(taskHeader.getWarehouseCode());
        agvTask.setContainerCode(taskHeader.getContainerCode());
        switch (taskHeader.getTaskType()) {
            case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
            case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                agvTask.setTaskType(QuantityConstant.AGV_TYPE_TAKE);
                agvTask.setPriority(100);
                agvTask.setFromPort(taskHeader.getPort());
                agvTask.setToPort(taskHeader.getToLocation());
                break;
            case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
            case QuantityConstant.TASK_TYPE_EMPTYSHIPMENT:
                agvTask.setTaskType(QuantityConstant.AGV_TYPE_RELEASE);
                agvTask.setPriority(100);
                agvTask.setFromPort(taskHeader.getFromLocation());
                agvTask.setToPort(taskHeader.getPort());
                break;
            case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
            case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
            case QuantityConstant.TASK_TYPE_VIEW:
                agvTask.setTaskType(QuantityConstant.AGV_TYPE_RELEASE);
                agvTask.setPriority(100);
                agvTask.setFromPort(taskHeader.getFromLocation());
                agvTask.setToPort(taskHeader.getPort());
                break;
        }
        agvTask.setPriority(100);
        AgvTaskCS taskCS=this.getAgvTaskByHeaderId(taskHeader,agvTask.getTaskType());
        if(taskCS!=null){
            //有agv任务则不重新生成
            return taskCS;
        }

        agvTask.setTaskHeaderId(taskHeader.getId());
        agvTask.setTaskHeaderType(taskHeader.getTaskType());

        Container container=containerService.getContainerByCode(taskHeader.getContainerCode(),taskHeader.getWarehouseCode());
        agvTask.setZoneCode(taskHeader.getZoneCode());
        agvTask.setNumber(container.getNumber());
        agvTask.setWarehouseCode(taskHeader.getWarehouseCode());
        agvTask.setStatus(QuantityConstant.AGV_TASK_STATUS_BUILD);
        agvTask.setCreatedTime(new Date());
        agvTask.setCreatedBy(taskHeader.getCreatedBy());
        if (!this.save(agvTask)) {
            throw new ServiceException("保存AGV任务失败");
        }
        return agvTask;
    }

    /**
     * 第2段任务
     * @param taskHeader
     * @param agvTaskCS
     * @return
     */
    public AgvTaskCS saveAGVTaskByTaskReturn(TaskHeader taskHeader,AgvTaskCS agvTaskCS) {
        AgvTaskCS agvTask = new AgvTaskCS();
        agvTask.setWarehouseCode(taskHeader.getWarehouseCode());
        agvTask.setContainerCode(taskHeader.getContainerCode());
        switch (taskHeader.getTaskType()) {
            case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
            case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
            case QuantityConstant.TASK_TYPE_VIEW:
                //补充入库,分拣出库,出库查看,agv回库
                agvTask.setTaskType(QuantityConstant.AGV_TYPE_TAKE);
                agvTask.setFromPort(taskHeader.getPort());
                if(agvTaskCS.getZoneCode().equals("V")&&taskHeader.getPort().equals(QuantityConstant.AGV_PORT_CS)){
                    agvTask.setToPort("");
                }else{
                    agvTask.setToPort(taskHeader.getToLocation());
                }
                agvTask.setPriority(100);
                break;
            default:
                break;
        }
        AgvTaskCS taskCS=this.getAgvTaskByHeaderId(taskHeader,agvTask.getTaskType());
        if(taskCS!=null){
            //有agv任务则不重新生成
            return taskCS;
        }
        agvTask.setPreTaskNo(agvTaskCS.getId());
        agvTask.setTaskHeaderType(taskHeader.getTaskType());

        Container container=containerService.getContainerByCode(taskHeader.getContainerCode(),taskHeader.getWarehouseCode());
        agvTask.setZoneCode(taskHeader.getZoneCode());
        agvTask.setNumber(container.getNumber());
        agvTask.setWarehouseCode(taskHeader.getWarehouseCode());
        agvTask.setTaskHeaderId(taskHeader.getId());
        agvTask.setStatus(QuantityConstant.AGV_TASK_STATUS_BUILD);//1
        agvTask.setCreatedTime(new Date());
        agvTask.setCreatedBy(ShiroUtils.getLoginName());
        if (!this.save(agvTask)) {
            throw new ServiceException("保存AGV任务失败");
        }
        return agvTask;
    }




    /**
     * 长沙大立库,单车agv任务:入库选择站台:保存站台,生成agv点到点任务
     * @param taskHeader
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setLKPort(TaskHeader taskHeader){
        if(taskHeader.getId()==null||taskHeader.getId()==0){
            return AjaxResult.error("任务id为空");
        }
        TaskHeader task=taskHeaderService.getById(taskHeader.getId());
        if(task==null){
            return AjaxResult.error("找不到任务");
        }
        if(StringUtils.isNotEmpty(taskHeader.getZoneCode())){
            task.setZoneCode(taskHeader.getZoneCode());
        }
        if(task.getZoneCode().equals("V")){
            //AGV叉车库:建立agv任务
            AjaxResult ajaxResult=setAgvPort( taskHeader);
            return ajaxResult;
        }

        AjaxResult ajaxResult=checkLocationData(taskHeader,task);
        if(ajaxResult.hasErr()){
            return ajaxResult;
        }
        //长沙大立库建立AGV任务

        task.setPort(taskHeader.getPort());
        task.setToPort(taskHeader.getToPort());
        taskHeaderService.updateById(task);
        switch (task.getTaskType()) {
            case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
            case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                //入库从开始就创建,出库等立库任务完成再创建
                if(task.getZoneCode().equals("JLK")){
                    task.setPort(QuantityConstant.JIJIA_PORT);
                }
                AgvTaskCS agvTask2=saveAgvTaskBySimpleAgv(task,null);
                break;
            default:
                return AjaxResult.success("不需要创建AGV任务");
        }

        return AjaxResult.success();
    }
    /**
     * 机加库,单车agv任务:入库选择站台:保存站台,生成agv点到点任务
     * @param task
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TaskHeader setJLKPort(TaskHeader task){
        if(!task.getZoneCode().equals("JLK")){
            return task;
        }
        if(StringUtils.isNotEmpty(task.getPickingCartPos())){
            task.setToPort(task.getPickingCartPos());
        }
        switch (task.getTaskType()) {
            case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
            case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                task.setPort(QuantityConstant.JIJIA_PORT);
                AgvTaskCS agvTask2=saveAgvTaskBySimpleAgv(task,null);
                break;
            case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
            case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
            case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
            case QuantityConstant.TASK_TYPE_EMPTYSHIPMENT:
            case QuantityConstant.TASK_TYPE_CYCLECOUNT:
            case QuantityConstant.TASK_TYPE_VIEW:
                task.setPort(QuantityConstant.JIJIA_PORT_SORTING);
                //入库从开始就创建,出库等立库任务完成再创建
//                AgvTaskCS agvTask3=saveAgvTaskBySimpleAgv(task,null);
                break;
            case QuantityConstant.TASK_TYPE_OVER_STATION:
                AgvTaskCS agvTask4 = saveAgvTaskBySimpleAgv(task, null);
                break;
            default:
                break;
        }

        return task;
    }

    /**
     * agv搬运任务
     * @param task
     * @param agvtask
     * @return
     */
    @Override
    public AgvTaskCS saveAgvTaskBySimpleAgv(TaskHeader task,AgvTaskCS agvtask){

        if(StringUtils.isNotEmpty(task.getToPort())){
            Station station=stationService.getStaionByCode(task.getToPort(),task.getWarehouseCode());
            if (station == null) {
                throw new ServiceException(task.getToPort() + "点位信息不存在");
            }
            if (station.getStationType() == 2 || station.getStationType() == 4 ) {
                AgvTaskCS agvTaskCS=new AgvTaskCS();
                agvTaskCS.setZoneCode(task.getZoneCode());
                agvTaskCS.setContainerCode(task.getContainerCode());
                agvTaskCS.setPriority(100);
                agvTaskCS.setTaskType(QuantityConstant.AGV_TYPE_MOVE);
                agvTaskCS.setInternalTaskType(task.getInternalTaskType());
                agvTaskCS.setTaskHeaderId(task.getId());
                agvTaskCS.setStatus(QuantityConstant.AGV_TASK_STATUS_BUILD);//1
                agvTaskCS.setWarehouseCode(task.getWarehouseCode());
                agvTaskCS.setCreatedTime(new Date());
                agvTaskCS.setCreatedBy(ShiroUtils.getLoginName());
                //长沙agv单车
                agvTaskCS.setNumber("2");

                if(agvtask!=null){
                    agvTaskCS.setPreTaskNo(agvtask.getId());
                }
                agvTaskCS.setFromPort(task.getPort());
                agvTaskCS.setToPort(task.getToPort());
                Station stationA=stationService.getStaionByCode(task.getPort(),task.getWarehouseCode());
                switch (task.getTaskType()) {
                    case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
                    case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                        agvTaskCS.setToPort(task.getPort());
                        if(stationA!=null&&StringUtils.isNotEmpty(stationA.getConnectCode())){
                            agvTaskCS.setToPort(stationA.getConnectCode());
                        }
                        agvTaskCS.setFromPort(task.getToPort());

                        break;
                    case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
                    case QuantityConstant.TASK_TYPE_EMPTYSHIPMENT:
                        agvTaskCS.setFromPort(task.getPort());
                        if(stationA!=null&&StringUtils.isNotEmpty(stationA.getConnectCode())){
                            agvTaskCS.setFromPort(stationA.getConnectCode());
                        }
                        agvTaskCS.setToPort(task.getToPort());
                        break;
                    default:
                        break;
                }

                AgvTaskCS taskCS=this.getAgvTaskByHeaderId(task,agvTaskCS.getTaskType());
                if(taskCS!=null){
                    return taskCS;
                }
                if(StringUtils.isNotEmpty(agvTaskCS.getToPort())){
                    if(agvTaskCS.getToPort().equals(agvTaskCS.getFromPort())){
                        return null;
                    }
                }
                if(!this.save(agvTaskCS)){
                    throw new ServiceException("保存AGV任务失败");
                }
                return  agvTaskCS;
            }
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setAgvPort(TaskHeader taskHeader){
        if(taskHeader.getId()==null||taskHeader.getId()==0){
            return AjaxResult.error("任务id为空");
        }
        if(StringUtils.isEmpty(taskHeader.getPort())){
            return AjaxResult.error("库区站台为空");
        }
//        if(StringUtils.isEmpty(taskHeader.getToPort())){
//            return AjaxResult.error("地面站台为空");
//        }
        TaskHeader task=taskHeaderService.getById(taskHeader.getId());
        if(task==null){
            return AjaxResult.error("找不到任务");
        }
        AjaxResult ajaxResult=checkLocationData(taskHeader,task);
        if(ajaxResult.hasErr()){
            return ajaxResult;
        }
        task.setPort(taskHeader.getPort());
        task.setToPort(taskHeader.getToPort());
        if(StringUtils.isNotEmpty(taskHeader.getToLocation())){
            task.setToLocation(taskHeader.getToLocation());
        }

//        task.setStatus(QuantityConstant.TASK_STATUS_RELEASE);

        String tolocation=task.getToLocation();
        AgvTaskCS agvTaskCS=null;

        String warehouseCode=task.getWarehouseCode();

        if(warehouseCode.equals(QuantityConstant.WAREHOUSE_CS)&&task.getZoneCode().equals("V")){
            AgvTaskCS agvTask=this.saveAGVTaskByTask(task);
            switch (task.getTaskType()) {
                case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
                case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
                case QuantityConstant.TASK_TYPE_VIEW:
                    AgvTaskCS agvTask1=this.saveAGVTaskByTaskReturn(task,agvTask);
                    break;
                case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
                case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                    if(StringUtils.isNotEmpty(task.getToPort())){
                        AgvTaskCS agvTask2=saveAgvTaskBySimpleAgv(task,null);
                        if(agvTask2!=null){
                            agvTask.setPreTaskNo(agvTask2.getId());
                            this.updateById(agvTask);
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        if(StringUtils.isNotEmpty(taskHeader.getToLocation())){
            //任务表有目的库位,任务表目的库位和起点库位不同,则释放目的库位
            if(StringUtils.isNotEmpty(tolocation)&&!task.getFromLocation().equals(tolocation)){
                locationService.updateContainerCodeAndStatus(tolocation,"",QuantityConstant.STATUS_LOCATION_EMPTY,task.getWarehouseCode());
            }
            Location location=locationService.getLocationByCode(taskHeader.getToLocation(),task.getWarehouseCode());
            if(StringUtils.isNotEmpty(location.getContainerCode())){
                locationService.updateContainerCodeAndStatus(taskHeader.getToLocation(),location.getContainerCode(),QuantityConstant.STATUS_LOCATION_LOCK,task.getWarehouseCode());
            }else{
                locationService.updateContainerCodeAndStatus(taskHeader.getToLocation(),"",QuantityConstant.STATUS_LOCATION_LOCK,task.getWarehouseCode());
            }
        }
        taskHeaderService.updateById(task);
        return AjaxResult.success();
    }

    public AjaxResult checkLocationData(TaskHeader taskHeader,TaskHeader task){
        if(task.getWarehouseCode().equals(QuantityConstant.WAREHOUSE_CS)&&task.getZoneCode().equals("V")){
        }else{
            return AjaxResult.success("不需要设置AGV站台");
        }
        Station station=stationService.getStaionByCode(taskHeader.getPort(),task.getWarehouseCode());
        if(station==null){
            return AjaxResult.error(taskHeader.getPort()+"站台不存在");
        }
        if(StringUtils.isNotEmpty(taskHeader.getToPort())){
            Station station1=stationService.getStaionByCode(taskHeader.getToPort(),task.getWarehouseCode());
            if(station1==null){
                return AjaxResult.error(taskHeader.getToPort()+"站台不存在");
            }
        }
        //库位不为空时,验证库位容器是否匹配
        if(StringUtils.isNotEmpty(taskHeader.getToLocation())){
            Location location=locationService.getLocationByCode(taskHeader.getToLocation(),task.getWarehouseCode());
            if(location==null){
                return AjaxResult.error("库位不存在,请填写正确库位");
            }

            if(StringUtils.isNotEmpty(task.getFromLocation())&&task.getFromLocation().equals(taskHeader.getToLocation())){
            }else{
                if(!location.getStatus().equals(QuantityConstant.STATUS_LOCATION_EMPTY)){
                    return AjaxResult.error("库位不是空闲状态,请输入空闲库位");
                }
                if(StringUtils.isNotEmpty(location.getContainerCode())){
                    return AjaxResult.error("库位上有托盘,请填写正确库位");
                }
            }

            if(!location.getZoneCode().equals(task.getZoneCode())){
                return AjaxResult.error("库位不是AGV库区的,请填写正确库位");
            }
            Container container=containerService.getContainerByCode(task.getContainerCode(),task.getWarehouseCode());
            ContainerType containerType=containerTypeService.getContainerTypeByCode(container.getContainerType(),task.getWarehouseCode());
            //库位 托盘类型匹配
            if(!containerType.getLocationType().contains(location.getLocationType())){
                return AjaxResult.error("库位类型与托盘类型不匹配,请填写正确库位");
            }
        }
        return AjaxResult.success();
    }
}