/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.youchain.businessdata.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.youchain.Netty.NettyUtils;
import com.youchain.basicdata.domain.*;
import com.youchain.basicdata.repository.*;
import com.youchain.basicdata.service.BoxService;
import com.youchain.basicdata.service.ItemService;
import com.youchain.basicdata.service.PointService;
import com.youchain.basicdata.service.impl.BoxServiceImpl;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.repository.AsnDetailRepository;
import com.youchain.businessdata.repository.TaskRepository;
import com.youchain.businessdata.service.*;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.quartz.utils.TimeNumberUtils;
import com.youchain.modules.system.service.DictService;
import com.youchain.modules.system.service.dto.DictDto;
import com.youchain.modules.system.service.dto.DictQueryCriteria;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.businessdata.repository.AgvTaskRepository;
import com.youchain.businessdata.service.dto.AgvTaskDto;
import com.youchain.businessdata.service.dto.AgvTaskQueryCriteria;
import com.youchain.businessdata.service.mapstruct.AgvTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;


/**
 * @author baobinglin
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-08-18
 **/
@Service
@RequiredArgsConstructor
@Slf4j
public class AgvTaskServiceImpl implements AgvTaskService {

    private final AgvTaskRepository agvTaskRepository;
    private final AgvTaskMapper agvTaskMapper;
    private final TaskRepository taskRepository;
    private final InventoryService inventoryService;
    private final PointRepository pointRepository;
    private final StockTypeRepository stockTypeRepository;
    private final AsnDetailRepository asnDetailRepository;
    private final EntityManager entityMapper;

    @Override
    public Map<String, Object> queryAll(AgvTaskQueryCriteria criteria, Pageable pageable) {
        Page<AgvTask> page = agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(agvTaskMapper::toDto));
    }

    @Override
    public List<AgvTaskDto> queryAll(AgvTaskQueryCriteria criteria) {
        return agvTaskMapper.toDto(agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public AgvTaskDto findById(Integer id) {
        AgvTask agvTask = agvTaskRepository.findById(id).orElseGet(AgvTask::new);
        ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", id);
        return agvTaskMapper.toDto(agvTask);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AgvTaskDto create(AgvTask resources) {
        return agvTaskMapper.toDto(agvTaskRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(AgvTask resources) {
        AgvTask agvTask = agvTaskRepository.findById(resources.getId()).orElseGet(AgvTask::new);
        ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", resources.getId());
        agvTask.copy(resources);
        agvTaskRepository.save(agvTask);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            agvTaskRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<AgvTaskDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AgvTaskDto agvTask : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("容器码", agvTask.getStockCode());
            map.put("容器类型", agvTask.getStockTypeCode());
            map.put("起点位置", agvTask.getStartSlotCode());
            map.put("终点位置", agvTask.getEndSlotCode());
            map.put("容器当前位置", agvTask.getSlotCode());
            map.put("任务状态", agvTask.getStatus());
            map.put("任务类型", agvTask.getType());
            map.put("下游任务号", agvTask.getJobId());
            map.put("工作类型", agvTask.getJobType());
            map.put("优先级", agvTask.getJobPriority());
            map.put("强制优先级", agvTask.getJobPriorityType());
            map.put("任务组", agvTask.getJobForce());
            map.put("任务组执行顺序", agvTask.getJobForceAsc());
            map.put("返回报文", agvTask.getJobMessage());
            map.put("变动时间", agvTask.getJobMessageTime());
            map.put("创建时间", agvTask.getCreateTime());
            map.put("开始时间", agvTask.getStartTime());
            map.put("完成时间", agvTask.getEndTime());
            map.put("创建人", agvTask.getCreateBy());
            map.put("修改人", agvTask.getUpdateBy());
            map.put("修改时间", agvTask.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 南瑞-AGV接口
     * @param agvTask
     * @return
     */
    @Override
    public synchronized String sendAgvTaskImpl(AgvTask agvTask) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        String api="";
        if (agvTask.getType().equals(BizStatus.AGV)) {
            //搬运任务
            jsonObject.put("requestId", agvTask.getId());
            jsonObject.put("missionCode", agvTask.getId());
            jsonObject.put("priority", agvTask.getJobPriority());
            jsonObject.put("containerModeCode", agvTask.getStockTypeCode());
            jsonObject.put("startPosition", agvTask.getStartSlotCode());
            jsonObject.put("endPosition", agvTask.getEndSlotCode());
//            jsonObject.put("viewBoardType", "");
            api=UrlApi.submitMission;
        }
        if (agvTask.getType().equals(BizStatus.AGV_R)){
            jsonObject.put("requestId", agvTask.getId());
            jsonObject.put("containerModeCode", agvTask.getStockTypeCode());
//            jsonObject.put("containerCode", agvTask.getStockTypeCode());
            jsonObject.put("position", agvTask.getEndSlotCode());
            api=UrlApi.containerIn;
        }
        if (agvTask.getType().equals(BizStatus.AGV_C)){
            jsonObject.put("requestId", agvTask.getId());
            jsonObject.put("position", agvTask.getEndSlotCode());
            api=UrlApi.containerOut;
        }
        String resultJson = HttpPostUtil.sendPostReq(api, jsonObject.toString());//返回ResponseJson*/
        JSONObject resulObject = JSON.parseObject(resultJson);
        System.out.println("result:"+resulObject);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("0")) {
            if (agvTask.getType().equals(BizStatus.AGV_R)||agvTask.getType().equals(BizStatus.AGV_C)){
                agvTask.setStatus(BizStatus.FINISH);
            }else {
                agvTask.setStatus(BizStatus.ATCALL);
            }
            agvTask.setJobMessage(resultJson);
            agvTask.setReqMessage(jsonObject.toString());
            agvTask.setStartTime(new Timestamp(new Date().getTime()));
            update(agvTask);
        } else {
            agvTask.setJobMessage(resultJson);
            agvTask.setReqMessage(jsonObject.toString());
            update(agvTask);
        }
        return resultJson;
    }

    @Override
    public synchronized String sendAgvTaskLXImpl(List<AgvTask> agvTasks) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        String agvCode = TimeNumberUtils.getXJTaskCode();
        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", agvCode);//库存组织 ID(或工厂代码，供应商代码)
        objMap.put("requestId", agvCode);//请求 id
        objMap.put("missionCode", agvCode);//任务编号
        objMap.put("missionType", "PICKER_MOVE");//任务类型 ：料箱
        objMap.put("viewBoardType", "");//上视识别类型:
        objMap.put("robotType", "PICKER");//机器人功能类型
        JSONArray robotModels = new JSONArray();
        objMap.put("robotModels", robotModels);//机器人具体型号
        JSONArray robotIds = new JSONArray();
        objMap.put("robotIds", robotIds);//机器人编号
        objMap.put("priority", "1");//数值越小，优先级越高，默认是 1
        objMap.put("templateCode", "");//作业流程模板编号
        objMap.put("lockRobotAfterFinish", false);//是否需要流程结束后机器人保持任务锁定状态
        objMap.put("unlockRobotId", "");//解锁当前小车的在上个任务的锁定状态
        objMap.put("unlockMissionCode", "");//当前小车的上一个任务
        objMap.put("idleNode", "");//作业流程完成后，指定机器人停放区域/点

        JSONArray missionDataArray = new JSONArray();
        for (int i = 0; i < agvTasks.size(); i++) {
            AgvTask agvTask = agvTasks.get(i);
            JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
            Map<String, Object> missionDataMap = new LinkedHashMap<>();
            missionDataMap.put("sequence", (i + 1));//序号
            missionDataMap.put("binCode", agvTask.getStockCode());//料箱号
            missionDataMap.put("startPosition", "");//料箱所在的起始点位
            missionDataMap.put("startSlotCode", agvTask.getStartSlotCode());//料箱所在的起始槽位
            missionDataMap.put("takeActionConfirm", false);//取料箱时之前是否需确认
            missionDataMap.put("endPosition", "");//料箱所在的目标点位
            missionDataMap.put("endSlotCode", agvTask.getEndSlotCode());//料箱所在的目标槽位
            missionDataMap.put("putActionConfirm", false);//放料箱时之前是否需要确认
            missionDataObj.putAll(missionDataMap);
            missionDataArray.add(missionDataObj);
        }

        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        System.out.println(jsonObject.toString());
        String resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission, jsonObject.toString());
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("0")) {
            for (int i = 0; i < agvTasks.size(); i++) {
                AgvTask agvTask = agvTasks.get(i);
                agvTask.setJobForce(agvCode);//任务组
                agvTask.setJobForceAsc((i + 1));
                agvTask.setStatus(BizStatus.ATCALL);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                agvTask.setStartTime(new Timestamp(new Date().getTime()));
                update(agvTask);
            }
        } else {
            for (int i = 0; i < agvTasks.size(); i++) {
                AgvTask agvTask = agvTasks.get(i);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                update(agvTask);
            }
        }
        return resultJson;
    }

    @Override
    public synchronized String sendAgvTaskGTImpl(List<AgvTask> agvTasks1, List<AgvTask> agvTasks2) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        String agvCode = TimeNumberUtils.getGTTaskCode();
        Map<String, Object> objMap = new LinkedHashMap<>();
        objMap.put("orgId", agvCode);//库存组织 ID(或工厂代码，供应商代码)
        objMap.put("requestId", agvCode);//请求 id
        objMap.put("missionCode", agvCode);//任务编号
        objMap.put("missionType", "ROLLER_MOVE");//任务类型 ：滚筒
        objMap.put("viewBoardType", "");//上视识别类型:
        JSONArray missionDataArray = new JSONArray();
        for (int i = 0; i < agvTasks1.size(); i++) {
            AgvTask agvTask = agvTasks1.get(i);
            JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
            Map<String, Object> missionDataMap = new LinkedHashMap<>();
            missionDataMap.put("sequence", (i + 1));//序号
            missionDataMap.put("binCode", agvTask.getStockCode());//料箱号
            missionDataMap.put("startDeviceCode", agvTask.getStartSlotCode());//料箱所在的起始槽位
            missionDataMap.put("endDeviceCode", agvTask.getEndSlotCode());//料箱所在的目标槽位
            missionDataMap.put("rollerLevel", 2);//层
            missionDataMap.put("rollerColumn", (i + 1));//列
            missionDataObj.putAll(missionDataMap);
            missionDataArray.add(missionDataObj);
        }
        int sum = agvTasks1.size();
        if (agvTasks2.size() > 0) {
            for (int i = 0; i < agvTasks2.size(); i++) {
                AgvTask agvTask = agvTasks2.get(i);
                JSONObject missionDataObj = new JSONObject(new LinkedHashMap<>());
                Map<String, Object> missionDataMap = new LinkedHashMap<>();
                missionDataMap.put("sequence", (sum + (i + 1)));//序号
                missionDataMap.put("binCode", agvTask.getStockCode());//料箱号
                missionDataMap.put("startDeviceCode", agvTask.getStartSlotCode());//料箱所在的起始槽位
                missionDataMap.put("endDeviceCode", agvTask.getEndSlotCode());//料箱所在的目标槽位
                missionDataMap.put("rollerLevel", 1);//层
                missionDataMap.put("rollerColumn", (i + 1));//列
                missionDataObj.putAll(missionDataMap);
                missionDataArray.add(missionDataObj);
            }
        }


        objMap.put("missionData", missionDataArray);
        jsonObject.putAll(objMap);
        System.out.println(jsonObject.toString());
        String resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission, jsonObject.toString());//返回ResponseJson*/
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("0")) {
            for (int i = 0; i < agvTasks1.size(); i++) {
                AgvTask agvTask = agvTasks1.get(i);
                agvTask.setJobForce(agvCode);//任务组
                agvTask.setJobForceAsc((i + 1));
                agvTask.setStatus(BizStatus.ATCALL);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                agvTask.setStartTime(new Timestamp(new Date().getTime()));
                update(agvTask);
            }
            for (int i = 0; i < agvTasks2.size(); i++) {
                AgvTask agvTask = agvTasks2.get(i);
                agvTask.setJobForce(agvCode);//任务组
                agvTask.setJobForceAsc((i + 1));
                agvTask.setStatus(BizStatus.ATCALL);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                agvTask.setStartTime(new Timestamp(new Date().getTime()));
                update(agvTask);
            }
        } else {
            for (int i = 0; i < agvTasks1.size(); i++) {
                AgvTask agvTask = agvTasks1.get(i);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                update(agvTask);
            }
            for (int i = 0; i < agvTasks2.size(); i++) {
                AgvTask agvTask = agvTasks2.get(i);
                agvTask.setJobMessage(resultJson);
                agvTask.setReqMessage(jsonObject.toString());
                update(agvTask);
            }
        }
        return resultJson;
    }

    @Override
    public synchronized String containerIn(String containerCode, String position, String enterOrientation) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        jsonObject.put("requestId", String.valueOf(new Date().getTime()));//请求 id
        jsonObject.put("containerType", "");//容器类型
        jsonObject.put("containerCode", containerCode);//容器编号
        jsonObject.put("position", position);//容器当前位置
        jsonObject.put("enterOrientation", enterOrientation);//角度
        return jsonObject.toString();
    }

    @Override
    public synchronized String containerOut(String containerCode) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        jsonObject.put("requestId", String.valueOf(new Date().getTime()));//请求 id
        jsonObject.put("containerType", "");//容器类型
        jsonObject.put("containerCode", containerCode);//容器编号
        jsonObject.put("position", "");//容器当前位置
        return jsonObject.toJSONString();
    }

    @Override
    public String containerQuery(String containerCode) {
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        jsonObject.put("nodeCode", "");//点位编码
        jsonObject.put("containerModelCode", "");//容器模型编码
        jsonObject.put("containerCode", containerCode);//容器编号
        jsonObject.put("areaCode", "");//区域编码
        jsonObject.put("emptyFullStatus", 2);//容器的空满状态 空 0  满 1  全部 2
        return jsonObject.toJSONString();
    }

    @Override
    public int QueryCount(String taskCode) {

        String jsonObject = "{\"taskCode\":\"" + taskCode + "\"}";//查询出库缓存输送线上满料箱总数
        String resultJson = HttpPostUtil.sendPostReq(UrlApi.QueryCount, jsonObject);
        JSONObject json = JSON.parseObject(resultJson);
        String queryCount = json.getString("queryCount");

        return Integer.parseInt(queryCount);
    }

    @Override
    public int querypoint(String pointCode) {
        String jsonObject = "{\"pointCode\":\"" + pointCode + "\"}";//查询出库缓存输送线上满料箱总数
        String resultJson = HttpPostUtil.sendPostReq(UrlApi.querypoint, jsonObject);
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("status") == null ? "" : resulObject.getString("status");
        if (code.equals("200")) {
            String data1 = resulObject.getString("data") == null ? "" : resulObject.getString("data");
            JSONArray jsonArray = JSON.parseArray(data1);
            int count = 0;
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject dataObject = JSON.parseObject(jsonArray.get(i).toString());
                String pointStatus = dataObject.getString("pointStatus") == null ? "" : dataObject.getString("pointStatus");
                count += Integer.parseInt(pointStatus);
            }
            return count;
        }
        return 0;
    }

    @Override
    public void getConveyorState(String conveyorId) {
        /*  String resultJson= HttpPostUtil.sendPostReq(UrlApi.agv_url, jsonObject.toString());//返回ResponseJson*/
        String resultJson = "{\n" +
                "\"success\":true,\n" +
                "\"code\":200,\n" +
                "\"message\":\"\",\n" +
                "\"conveyorId\":\"1\",\n" +
                "\"state\":\"1\"\n" +
                "}";
        JSONObject resulObject = JSON.parseObject(resultJson);
        String code = resulObject.getString("code") == null ? "" : resulObject.getString("code");
        if (code.equals("200")) {
            /**
             * state
             * 1：允许取货
             * 2：允许放货
             * 3、不允许取货
             * 4、不允许放货
             */
            String state = resulObject.getString("state") == null ? "" : resulObject.getString("state");
            if (state.equals("1")) {

            } else if (state.equals("2")) {

            } else if (state.equals("3")) {

            } else if (state.equals("4")) {

            }
        }

    }

    public AgvTask toEntity(AgvTaskDto agvTaskDto) {
        return agvTaskMapper.toEntity(agvTaskDto);
    }

    @Override
    @Transactional
    public void agvTaskCallback(String taskCode, String status) {
        // agvTask搬运任务
        AgvTask agvTask=agvTaskRepository.getById(Integer.valueOf(taskCode));
        // task库存任务
//        List<Task> tasks=taskRepository.getAgvTaskList(agvTask.getId(),BizStatus.ASN);
        Point startPoint=null;
        Point endPoint=null;
        if (status.equals("1")){
            // 开始执行
//            agvTask.setStatus(BizStatus.ATWORK);
        }else if (status.equals("2")){
            // 取料完成
            startPoint=pointRepository.findByCode(agvTask.getStartSlotCode());
            if (startPoint!=null) {
                startPoint.setAgvStatus(BaseStatus.FREE);
                startPoint.setStorageType(null);
                pointRepository.save(startPoint);
                agvTask.setStartTime(new Timestamp((new Date()).getTime()));
            }else {
                List<Task> taskList = taskRepository.findByAgvTask(agvTask.getId(), BizStatus.ALLOCATE);
                for (int i = 0; i < taskList.size(); i++) {
                    Task task = taskList.get(i);
                    if (task.getTaskType().equals(BizStatus.RM_CK)) {
                        /** 入库为料箱出库 出库所有的清空搬运任务关联的所有Point*/
                        Point point = task.getSrcPoint();
                        point.setAgvStatus(BaseStatus.FREE);
                        point.setStorageType(null);
                        pointRepository.save(point);
                    }
                }
            }
        } else if (status.equals("3")) {
            agvTask.setStatus(BizStatus.FINISH);
            agvTask.setEndTime(new Timestamp((new Date()).getTime()));
            // 放料完成
            endPoint=pointRepository.findByCode(agvTask.getEndSlotCode());
            if (endPoint!=null) {
                endPoint.setAgvStatus(BaseStatus.FREE);
                pointRepository.save(endPoint);
                if (agvTask.getJobType().equals(BizStatus.ASN)) {
                    List<Task> taskList = taskRepository.findByAgvTask(agvTask.getId(), BizStatus.RECEIVING);
                    if (taskList.size() > 0) {
                        if (taskList.get(0).getTaskType().equals(BizStatus.RM_RK)) {

                        } else {
                            List<Map<String, Object>> taskMapList = taskRepository.findByAgvTask(agvTask.getId()
                                    , taskList.get(0).getTaskType(), 1l,null);
                            if (taskMapList.size() > 0) {
                                /** 入库任务回调 生成库存 */
                                Inventory inventory = inventoryService.asnAddInventory(taskMapList);
                            }
                        }
                    }
                }
            }
            if (agvTask.getJobType().equals(BizStatus.PICK)) {
                List<Task> taskList=taskRepository.findByAgvTask(agvTask.getId());
                /** 出库任务回调 生成删除库存*/
                inventoryService.pickDelInventory(taskList);
            }

        } else if (status.equals("4")) {
            // 取消任务
            agvTask.setStatus(BizStatus.CANCEL);
            if (endPoint.getType().equals(BaseStatus.STORAGE)){
                endPoint.setAgvStatus(BaseStatus.FREE);
                pointRepository.save(endPoint);
            }
            if (startPoint.getType().equals(BaseStatus.STORAGE)){
                startPoint.setAgvStatus(BaseStatus.FREE);
                pointRepository.save(startPoint);
            }
        }
        agvTaskRepository.save(agvTask);
    }

    @Override
    public AgvTask findBycontainerCode(String containerCode) {
        return agvTaskRepository.findBycontainerCode(containerCode);
    }

    @Override
    public List<AgvTask> queryByAgvTask(String stockCode, String status, String type, int be_scan, String jobType) {
        return agvTaskRepository.queryByAgvTask(stockCode, status, type, be_scan, jobType);
    }

    @Override
    public List<AgvTask> queryByAgvTask(String stockCode, String type, String jobType) {
        String hql = " from AgvTask agv" +
                " where  agv.stockCode='" + stockCode + "' " +
                " and agv.type='" + type + "' " +
                " and agv.jobType='" + jobType + "' " +
                " and agv.status in ('OPEN','ATCALL') ";
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        return agvTaskList;
    }

    @Override
    public boolean findByendSlotCode(String endSlotCode,String type,String jobType) {
        String hql = " from AgvTask agv " +
                " where  agv.endSlotCode='" + endSlotCode + "' " +
                " and agv.type='"+type+"' " +
                " and agv.jobType='"+jobType+"' " +
                " and agv.status in ('ATCALL','UP_CONTAINER') ";

        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        if (agvTaskList.size() > 0) {
            return false;
        }
        return true;
    }

    @Override
    public AgvTask findByjobCode(String jobForce, String containerCode) {
        String hql = " from AgvTask agv where  agv.jobForce='" + jobForce + "' and agv.stockCode='" + containerCode + "' ";
        AgvTask agvTask = null;
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        if (agvTaskList.size() > 0) {
            agvTask = agvTaskList.get(0);
        }
        return agvTask;
    }

    @Override
    public List<AgvTask> findByjobCode(String jobForce) {
        String hql = " from AgvTask agv where  agv.jobForce='" + jobForce + "' ";
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        return agvTaskList;
    }

    @Override
    public AgvTask findByStockCode(String containerCode, String type, String jobType) {
        String hql = " from AgvTask agv where  agv.stockCode='" + containerCode + "' and agv.type='" + type + "' and agv.jobType='" + jobType + "'  order by agv.updateTime desc ";
        AgvTask agvTask = null;
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        if (agvTaskList.size() > 0) {
            agvTask = agvTaskList.get(0);
        }
        return agvTask;
    }

    @Override
    public List<AgvTask> findByAgvList(String type, String jobType) {
        String hql = " from AgvTask agv where  agv.type='" + type + "' "
                + " and agv.jobType='" + jobType + "' "
                + " and agv.status not in ('OPEN','FINISH','CANCEL') ";
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        return agvTaskList;
    }

    @Override
    public List<AgvTask> findById(List<Integer> ids) {
        String agvTaskIds = StringUtils.strip(ids.toString(), "[]");
        String hql = " from AgvTask agv where  agv.id in (" + agvTaskIds + ") ";
        Query query = entityMapper.createQuery(hql);
        List<AgvTask> agvTaskList = query.getResultList();
        return agvTaskList;
    }

    @Override
    public ApiResult pointStockRk(String storageType, Long id) {
        Point point=pointRepository.getById(id);
        System.out.println("调用容器入场接口");
        AgvTask agvTask=addAgvTask(BizStatus.AGV_R,storageType,null,point.getCode(),BizStatus.OPEN,BizStatus.ASN);
        JSONObject resultJson = JSONObject.parseObject(sendAgvTaskImpl(agvTask));
        if (!resultJson.getString("code").equals("0")){
            return ApiResult.fail(500, "容器入场失败", resultJson);
        }
        point.setStorageType(storageType);
        pointRepository.save(point);
        return ApiResult.fail(200, "操作成功", null);
    }
    @Override
    public ApiResult pointStockCk(String storageType, Long id) {
        Point point=pointRepository.getById(id);
        System.out.println("调用容器入场接口");
//        AgvTask agvTask = addAgvTask(BizStatus.AGV, stockType, task.getSrcPoint().getCode(),task.getDstPoint().getCode() , BizStatus.OPEN, BizStatus.ASN);

        AgvTask agvTask=addAgvTask(BizStatus.AGV_C,storageType,null,point.getCode(),BizStatus.OPEN,BizStatus.ASN);
        JSONObject resultJson = JSONObject.parseObject(sendAgvTaskImpl(agvTask));
        if (!resultJson.getString("code").equals("0")){
            return ApiResult.fail(500, "容器入场失败", resultJson);
        }
        point.setStorageType(storageType);
        pointRepository.save(point);
        return ApiResult.fail(200, "操作成功", null);
    }
    @Override
    public AgvTask addAgvTask(String type, String stockTypeCode, String startSlotCode, String endSlotCode, String status, String jobType) {
        AgvTask agvTask = new AgvTask();
        List<AgvTask> agvTaskList=agvTaskRepository.findByRptAgvTask(startSlotCode,endSlotCode);
        if (agvTaskList.size()>0){
            return agvTaskList.get(0);
        }
        agvTask.setType(type);
        String storageType=stockTypeRepository.findByCode(stockTypeCode).getMode();
        agvTask.setStockTypeCode(storageType);
        agvTask.setStartSlotCode(startSlotCode);
        agvTask.setEndSlotCode(endSlotCode);
        agvTask.setStatus(status);
        agvTask.setJobType(jobType);
        AgvTask agv=agvTaskRepository.save(agvTask);
        // 生成任务占用库位
        Point startPoint=pointRepository.findByCode(startSlotCode);
        Point endPoint=pointRepository.findByCode(endSlotCode);
        if (!type.equals(BizStatus.AGV_R)&&!type.equals(BizStatus.AGV_C)) {
            if (startPoint!=null&&startPoint.getType().equals("STORAGE")) {
                startPoint.setAgvStatus(BaseStatus.USED);
                pointRepository.save(startPoint);
            }
            if (endPoint!=null&&endPoint.getType().equals("STORAGE")) {
                endPoint.setAgvStatus(BaseStatus.USED);
                pointRepository.save(endPoint);
            }
        }
        return agv;
    }

    @Override
    public ApiResult addAgvTask(Long id, String pointEndCode) {
        Point startPoint=pointRepository.getById(id);
        Point endPoint=pointRepository.findByCode(pointEndCode);
        if (endPoint!=null){
            if (!startPoint.getStatus().equals(BaseStatus.FREE)){
                return ApiResult.fail(500,startPoint.getCode()+":被任务占用",null);
            }
            if (!endPoint.getStatus().equals(BaseStatus.FREE)){
                return ApiResult.fail(500,endPoint.getCode()+":被任务占用",null);
            }
            if (startPoint.getStorageType()==null||startPoint.getStorageType().length()<1){
                return ApiResult.fail(500,startPoint.getCode()+":没有容器",null);
            }
            AgvTask agvTask = addAgvTask(BizStatus.AGV, startPoint.getStorageType(), startPoint.getCode(),endPoint.getCode() , BizStatus.OPEN, BizStatus.ASN);
        }else {
            return ApiResult.fail(500,pointEndCode+":目标点错误",null);
        }
        return ApiResult.fail(200,"操作成功",null);
    }

    @Override
    @Transactional
    public ApiResult addAgvAsn(String areaCode,String billType) {
        List<Task> taskItemKeyList=taskRepository.findByGroupItemKey(BizStatus.RECEIVING,1,billType);
        for (int i = 0; i < taskItemKeyList.size(); i++) {
            Task taskItemKey=taskItemKeyList.get(i);
            // 搬运 起点
            String startPointCode=taskItemKey.getSrcPoint().getCode();
            // 搬运 终点
            String endPointCode = taskItemKey.getDstPoint().getCode();
            String stockTypeCode="";
            // 搬运容器类型类型
            if (taskItemKey.getTaskType().equals(BizStatus.FC_RK)){
                stockTypeCode=BizStatus.CTP_STO;
                if (taskItemKeyList.size()==1){

                }else {
                    return ApiResult.fail(201,"已读取到成品入库RFID票数:"+taskItemKeyList.size(),null);
                }
            }else if(taskItemKey.getTaskType().equals(BizStatus.RM_RK)){
                stockTypeCode=BizStatus.LXZ_STO;
                if (taskItemKeyList.size()==3){
                    endPointCode=taskItemKey.getDstPoint().getBeatCode();
                }else {
                    return ApiResult.fail(201,"已读取到料箱入库RFID票数:"+taskItemKeyList.size(),null);
                }
            }else if(taskItemKey.getTaskType().equals(BizStatus.SM_RK)){
                stockTypeCode=BizStatus.TP_STO;
                if (taskItemKeyList.size()==1){

                }else {
                    return ApiResult.fail(201,"已读取到半成品入库RFID票数:"+taskItemKeyList.size(),null);
                }
            }
            // 生成AgvTask搬运任务
            AgvTask agvTask = addAgvTask(BizStatus.AGV, stockTypeCode, startPointCode,endPointCode , BizStatus.OPEN, BizStatus.ASN);
            // 入库的Task任务
            List<Task> taskList=taskRepository.findByItemKey(taskItemKey.getItemKey().getId(), taskItemKey.getTaskStatus());
            for (int j = 0; j < taskList.size(); j++) {
                Task task=taskList.get(j);
                task.setAgvTask(agvTask);
                if (stockTypeCode.equals("LXZ")){
                    task.setTaskStatus(BizStatus.PUTAWAY);
                }
                taskRepository.save(task);
            }
        }
        return ApiResult.success(200, "操作成功", null);
    }
    //料想入库
    public ApiResult addAgvAsnLx(String areaCode,String billType) {
        // 收货明细
        List<AsnDetail> asnDetailList=asnDetailRepository.findByAsnBillType(billType);
        // 查询待收货的 Task
        List<Task> taskList=taskRepository.findByItemType(BizStatus.RECEIVING, 1, billType);
        for (int i = 0; i < taskList.size(); i++) {
            Task task=taskList.get(i);
            task.setMoveQty(task.getPlanQty());
            for (int j = 0; j < asnDetailList.size(); j++) {
                AsnDetail asnDetail=asnDetailList.get(i);
                //匹配 收货明细
                if (task.getItemKey().getItem().getId()==asnDetail.getItem().getId()&&asnDetail.getOrderQty()>asnDetail.getReceivedQty()){
                    asnDetail.setReceivedQty(asnDetail.getReceivedQty()+task.getMoveQty());
                }else {
                    return ApiResult.success(500, "无匹配收货单", "");
                }
            }

        }
        return ApiResult.success(200, "操作成功", "");
    }
    @Override
    public ApiResult addAgvAsnTage() {
        return null;
    }


    public void sendStockRk(String storageType, String pointCode) {
        System.out.println();

        /*AgvTask agvTask = new AgvTask();
        agvTask.setEndSlotCode(pointCode);
        agvTask.setType(BizStatus.);
        this.type=type;
        this.stockCode=stockCode;
        this.startSlotCode=startSlotCode;
        this.endSlotCode=endSlotCode;
        this.status=status;
        this.jobType=jobType;*/
    }

}
