package com.huaheng.pc.task.agvTask.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaheng.api.acs.service.AcsService;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.Wrappers;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.aspectj.lang.annotation.Log;
import com.huaheng.framework.aspectj.lang.constant.BusinessType;
import com.huaheng.framework.web.controller.BaseController;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.framework.web.page.PageDomain;
import com.huaheng.framework.web.page.TableDataInfo;
import com.huaheng.framework.web.page.TableSupport;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.points.service.PointsService;
import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
import com.huaheng.pc.system.user.domain.User;
import com.huaheng.pc.system.user.service.IUserService;
import com.huaheng.pc.task.agvTask.domain.AgvTask;
import com.huaheng.pc.task.agvTask.service.IAgvTaskService;
import com.huaheng.pc.task.taskDetail.domain.TaskDetail;
import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/task/agvTask")
public class AgvTaskController extends BaseController {
    private String prefix="task/agvTask";


    @Resource
    private IAgvTaskService agvTaskService;
    @Resource
    private PointsService pointsService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private ContainerService containerService;
    @Resource
    private InventoryDetailService inventoryDetailService;
    @Resource
    private IUserService userService;
    @Resource
    private AcsService acsService;

    @RequiresPermissions("task:agvTask:view")
    @GetMapping()
    public String agvTask() {

        return prefix + "/agvTask";
    }
    /**
     * 查询任务列表
     */
    @RequiresPermissions("task:agvTask:list")
    @Log(title = "任务-上架任务", operating = "查看任务列表", action = BusinessType.GRANT)
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(AgvTask agvTask, @ApiParam(name="taskType",value="类型") Integer taskType,
                              @ApiParam(name="createdBegin",value="类型") String createdBegin, @ApiParam(name="createdEnd",value="类型") String createdEnd) {
        LambdaQueryWrapper<AgvTask> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(AgvTask::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .eq(StringUtils.isNotNull(taskType), AgvTask::getTaskType,taskType)
                .eq(StringUtils.isNotNull(agvTask.getId()), AgvTask::getId,agvTask.getId())
                .eq(StringUtils.isNotEmpty(agvTask.getContainerCode()), AgvTask::getContainerCode,agvTask.getContainerCode())
                .eq(StringUtils.isNotEmpty(agvTask.getFromPort()), AgvTask::getFromPort,agvTask.getFromPort())
                .eq(StringUtils.isNotEmpty(agvTask.getToPort()), AgvTask::getToPort,agvTask.getToPort())
                .eq(StringUtils.isNotNull(agvTask.getPriority()), AgvTask::getPriority,agvTask.getPriority())
                .gt(StringUtils.isNotEmpty(createdBegin), AgvTask::getCreatedTime,createdBegin)
                .lt(StringUtils.isNotEmpty(createdEnd), AgvTask::getCreatedTime,createdEnd)
                .orderByAsc(AgvTask::getStatus)
                .orderByDesc(AgvTask::getId);

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        /**
         * 使用分页查询
         */
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)){
            Page<AgvTask> page = new Page<>(pageNum, pageSize);
            IPage<AgvTask> iPage = agvTaskService.page(page, lambdaQueryWrapper);
            List<AgvTask> iPages = iPage.getRecords();
            return getMpDataTable(iPages, iPage.getTotal());
        } else {
            List<AgvTask> list = agvTaskService.list(lambdaQueryWrapper);
            return getDataTable(list);
        }
    }

    @RequiresPermissions("task:agvTask:execute")
    @Log(title = "任务-任务管理", operating = "下发立库任务", action = BusinessType.INSERT)
    @PostMapping( "/executes")
    @ResponseBody
    public AjaxResult executes(String ids)
    {
        if (StringUtils.isEmpty(ids)){
            return AjaxResult.error("ids不能为空");
        }
        String[] idList = ids.split(",");
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.executeAGVTask(idList);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }
    @RequiresPermissions("task:agvTask:execute")
    @Log(title = "任务-任务管理", operating = "下发立库任务", action = BusinessType.INSERT)
    @PostMapping( "/execute")
    @ResponseBody
    public AjaxResult execute(String id)
    {
        if (StringUtils.isEmpty(id)){
            return AjaxResult.error("id不能为空");
        }
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.executeAGVTask(id);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }

    @RequiresPermissions("task:agvTask:cancels")
    @Log(title = "AGV任务-任务批量取消", operating = "批量取消AGV任务", action = BusinessType.DELETE)
    @PostMapping( "/cancels")
    @ResponseBody
    public AjaxResult cancels(String ids)
    {
        if (StringUtils.isEmpty(ids)){
            return AjaxResult.error("ids不能为空");
        }
        String[] idList = ids.split(",");
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.cancelAGVTasks(idList);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }

    @RequiresPermissions("task:agvTask:cancel")
    @Log(title = "AGV任务-任务取消", operating = "取消AGV任务", action = BusinessType.INSERT)
    @PostMapping( "/cancel")
    @ResponseBody
    public AjaxResult cancel(String id)
    {
        if (StringUtils.isEmpty(id)){
            return AjaxResult.error("id不能为空");
        }
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.cancelAGVTask(id);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }
    @RequiresPermissions("task:agvTask:complete")
    @Log(title = "AGV任务-任务完成", operating = "完成AGV任务", action = BusinessType.INSERT)
    @PostMapping( "/complete")
    @ResponseBody
    public AjaxResult complete(String id)
    {
        if (StringUtils.isEmpty(id)){
            return AjaxResult.error("id不能为空");
        }

        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.completeAGVTask(id);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }

    @RequiresPermissions("task:agvTask:completes")
    @Log(title = "AGV任务-批量任务完成", operating = "批量完成AGV任务", action = BusinessType.DELETE)
    @PostMapping( "/completes")
    @ResponseBody
    public AjaxResult completes(String ids)
    {
        if (StringUtils.isEmpty(ids)){
            return AjaxResult.error("id不能为空");
        }
        String[] idList = ids.split(",");
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult1 = agvTaskService.completeAGVTask(idList);
                return ajaxResult1;
            }
        });
        return ajaxResult;
    }

    @RequiresPermissions("task:agvTask:view")
    @GetMapping("/agvOperate")
    public String agvOperate() {
        return prefix + "/agvOperate";
    }

    @RequiresPermissions("task:agvTask:view")
    @GetMapping("/agvMenu")
    public String agvMenu() {
        return prefix + "/agvMenu";
    }

    @RequiresPermissions("task:agvTask:goodsShelfNo")
    @Log(title = "AGV 货架", operating = "AGV 货架", action = BusinessType.DELETE)
    @PostMapping( "/goodsShelfNo")
    @ResponseBody
    public List<Map<String, Object>> goodsShelfNo()
    {
        return pointsService.selectShlfno(ShiroUtils.getWarehouseCode());
    }

    /**
     * AGV界面中完成任务
     */
    @RequiresPermissions("task:agvTask:add")
    @Log(title = "任务-任务管理", operating = "PC完成AGV任务", action = BusinessType.UPDATE)
    @PostMapping( "/completeTaskByAGV")
    @ResponseBody
    public AjaxResult completeTaskByAGV(Integer taskId,Integer id,String num) throws Exception {
        AjaxResult ajaxResult = handleMultiProcess(new MultiProcessListener() {
            @Override
            public AjaxResult doProcess() {
                AjaxResult ajaxResult = agvTaskService.completTasks(id.toString());
//                AjaxResult ajaxResult = taskHeaderService.completeTaskByWMS(Convert.toIntArray(taskId.toString()),null);
                return ajaxResult;
            }
        });
        return ajaxResult;
    }

    @RequiresPermissions("task:agvTask:add")
    @GetMapping("/add")
    public String add() {
        return prefix + "/add";
    }

    /**
     * AGV界面中完成任务
     */
//    @RequiresPermissions("task:agvTask:add")
    @Log(title = "任务-AGV创建", operating = "AGV任务创建", action = BusinessType.INSERT)
    @PostMapping( "/add")
    @ResponseBody
    public AjaxResult add(AgvTask agvTask) {
        if(StringUtils.isNull(agvTask)){
            return AjaxResult.error("agv任务信息不能为空");
        }
        if(StringUtils.isEmpty(agvTask.getDestinationLocation())){
            return AjaxResult.error("agv任务信息 货架上位点不能为空");
        }
        if(StringUtils.isEmpty(agvTask.getContainerCode())){
            return AjaxResult.error("agv任务信息 托盘号不能为空");
        }
        if(StringUtils.isNull(agvTask.getPriority())){
            return AjaxResult.error("agv任务信息 优先级不能为空");
        }
        if(StringUtils.isEmpty(agvTask.getOrientation())){
            return AjaxResult.error("agv任务信息 方向不能为空");
        }
        Container container = containerService.findContainerByCodeType(agvTask.getContainerCode(),QuantityConstant.AGV_CONTAINER_TYPE,ShiroUtils.getWarehouseCode());
        if(container==null){
            return AjaxResult.error(agvTask.getContainerCode()+" 托盘不是AGV容器。");
        }
        if(QuantityConstant.STATUS_CONTAINER_LOCK.equals(container.getStatus())){
            return AjaxResult.error("容器号"+container.getCode()+" 被锁定!");
        }
        agvTask.setToPort(container.getGoodsShelfNo());
        AjaxResult agvTask1 = agvTaskService.createAGVTask(agvTask);
        return agvTask1;
    }

    /**
     * 获取当前货架要完成的任务
     *      *
     */
    @ResponseBody
    @PostMapping("/getGoodsShelfNos")
//    @RequiresPermissions("task:agvMenuTask:list")
    @Log(title = "AGV", operating ="任务显示", action = BusinessType.OTHER)
    public List<TaskDetail> GetGoodShelfNos(String goodsShelfNo, String station){
        String goodsShelf=goodsShelfNo.substring(0,5);
        String shlefs=goodsShelfNo.substring(5,6);
        String shlef=null;
        if(shlefs.equals("A")){
            shlef="1";
        }else {
            shlef="3";
        }
        station="ws0"+station;
        List<TaskDetail> result = taskHeaderService.selectList(goodsShelf,shlef,station);
        if(result!=null || result.size()>0) {
            for (TaskDetail t : result) {
                InventoryDetail inventory = new InventoryDetail();
                inventory.setContainerCode(t.getContainerCode());
                inventory.setCompanyCode(t.getCompanyCode());
                inventory.setWarehouseCode(t.getWarehouseCode());
                inventory.setMaterialCode(t.getMaterialCode());
                List<InventoryDetail> inventories = inventoryDetailService.selectListEntityByEqual(inventory);
                BigDecimal number = inventoryDetailService.addQty(inventories);
                t.setWarehouseQty(number);

                if(300==t.getTaskType().intValue() ||400==t.getTaskType().intValue()) {
                    if (number.compareTo(t.getQty()) > 0) {
                        t.setRemainder((number.subtract(t.getQty())));
                    } else {
                        t.setRemainder(new BigDecimal(0));
                    }
                }else if(100==t.getTaskType().intValue() || 200==t.getTaskType().intValue()){
                    t.setRemainder((number.add(t.getQty())));
                }else{
                    t.setRemainder(number);
                }
                User user =new User();
                user =userService.selectUserByLoginName(t.getLastUpdatedBy());
                if(user !=null){
                    t.setLastUpdatedBy(user.getUserName());
                }
                inventoryDetailService.selectUwarehouse(t);

            }
        }
        return  result;
    }
    /**
     * 获取当前货架要完成的任务
     *      *
     */
    @ResponseBody
    @PostMapping("/getGoodsShelfNo")
//    @RequiresPermissions("task:agvMenuTask:list")
    @Log(title = "AGV", operating ="任务显示", action = BusinessType.OTHER)
    public List<TaskDetail> GetGoodShelfNo(String goodsShelfNo,String station){
        String goodsShelf=goodsShelfNo.substring(0,5);
        String shlefs=goodsShelfNo.substring(5,6);
        String shlef=null;
        if(shlefs.equals("A")){
            shlef="1";
        }else {
            shlef="3";
        }
        station="ws0"+station;
        List<TaskDetail> result = taskHeaderService.selectList(goodsShelf,shlef,station);
        if(result!=null || result.size()>0) {
            for (TaskDetail t : result) {
                InventoryDetail inventory = new InventoryDetail();
                inventory.setContainerCode(t.getContainerCode());
                inventory.setCompanyCode(t.getCompanyCode());
                inventory.setWarehouseCode(t.getWarehouseCode());
                inventory.setMaterialCode(t.getMaterialCode());
                List<InventoryDetail> inventories = inventoryDetailService.selectListEntityByEqual(inventory);
                BigDecimal number = inventoryDetailService.addQty(inventories);
                t.setWarehouseQty(number);
                if(300==t.getTaskType().intValue() ||400==t.getTaskType().intValue()) {
                    if (number.compareTo(t.getQty()) > 0) {
                        t.setRemainder((number.subtract(t.getQty())));
                    } else {
                        t.setRemainder(new BigDecimal(0));
                    }
                }else if(100==t.getTaskType().intValue() || 200==t.getTaskType().intValue()){
                    t.setRemainder((number.add(t.getQty())));
                }else{
                    t.setRemainder(number.add(t.getQty()));
                }
                User user =new User();
                user =userService.selectUserByLoginName(t.getLastUpdatedBy());
                if(user !=null){
                    t.setLastUpdatedBy(user.getUserName());
                }
                inventoryDetailService.selectUwarehouse(t);

            }
        }

        if(shlefs.equals("A")){
            shlef="3";
        }else {
            shlef="1";
        }
        List<TaskDetail> taskDetails = taskHeaderService.selectList(goodsShelf,shlef,station);

        if(taskDetails!=null || taskDetails.size()>0) {
            for(TaskDetail t:taskDetails){
                InventoryDetail inventory = new InventoryDetail();
                inventory.setContainerCode(t.getContainerCode());
                inventory.setCompanyCode(t.getCompanyCode());
                inventory.setWarehouseCode(t.getWarehouseCode());
                inventory.setMaterialCode(t.getMaterialCode());
                List<InventoryDetail> inventorys = inventoryDetailService.selectListEntityByEqual(inventory);
                BigDecimal number =inventoryDetailService.addQty(inventorys);
                t.setWarehouseQty(number);
                if(300==t.getTaskType().intValue() ||400==t.getTaskType().intValue()) {
                    if (number.compareTo(t.getQty()) > 0) {
                        t.setRemainder((number.subtract(t.getQty())));
                    } else {
                        t.setRemainder(new BigDecimal(0));
                    }
                }else if(100==t.getTaskType().intValue() || 200==t.getTaskType().intValue()){
                    t.setRemainder((number.add(t.getQty())));
                }else{
                    t.setRemainder(number.add(t.getQty()));
                }

                User user =new User();
                user =userService.selectUserByLoginName(t.getLastUpdatedBy());
                if(user !=null){
                    t.setLastUpdatedBy(user.getUserName());
                }
                inventoryDetailService.selectUwarehouse(t);
            }
        }
        result.addAll(taskDetails);
        return  result;
    }
    @GetMapping("/remove")
    public String locationStatu()
    {
        return prefix + "/remove";
    }

    /**
     * AGV 任务取消
     */
//    @RequiresPermissions("task:agvMenuTask:remove")
    @Log(title = "AGV 任务取消", action = BusinessType.DELETE)
    @PostMapping("/taskCancel")
    @ResponseBody
    public AjaxResult TaskCancel(String message)
    {
        return acsService.taskCancel(message);
    }

    /**
     * 获取要完成的任务
     *      *
     */
    @ResponseBody
    @PostMapping("/getTask")
//    @RequiresPermissions("task:agvMenuTask:list")
    @Log(title = "AGV", operating ="任务显示", action = BusinessType.OTHER)
    public List<TaskDetail> getTask(String station){
        station="ws0"+station;
        List<TaskDetail> result = taskHeaderService.selectTaskList(station);
        result.forEach(t->{
            InventoryDetail inventory=new InventoryDetail();
            inventory.setContainerCode(t.getContainerCode());
            inventory.setCompanyCode(t.getCompanyCode());
            inventory.setWarehouseCode(t.getWarehouseCode());
            inventory.setMaterialCode(t.getMaterialCode());
            List<InventoryDetail> inventorys = inventoryDetailService.selectListEntityByEqual(inventory);
            BigDecimal number =inventoryDetailService.addQty(inventorys);
            t.setWarehouseQty(number);
            if("s".equals(t.getTaskType())) {
                if (number.compareTo(t.getQty()) > 0) {
                    t.setRemainder(new BigDecimal(number.compareTo(t.getQty())));
                } else {
                    t.setRemainder(new BigDecimal(0));
                }
            }else if("r".equals(t.getTaskType())){
                t.setRemainder((number.add(t.getQty())));
            }else{
                t.setRemainder((number.add(t.getQty())));
            }
            User user =new User();
            user =userService.selectUserByLoginName(t.getLastUpdatedBy());
            if(user !=null){
                t.setLastUpdatedBy(user.getUserName());
            }
            inventoryDetailService.selectUwarehouse(t);
        });
        return  result;
    }

    /**
     * AGV 旋转方向
     */
//    @RequiresPermissions("task:agvMenuTask:edit")
    @Log(title = "AGV 旋转方向", action = BusinessType.UPDATE)
    @PostMapping("/TurnOriention")
    @ResponseBody
    public AjaxResult TurnOriention(String carNo,String orientation)
    {
        if(StringUtils.isEmpty(carNo)){
            return AjaxResult.error("没有货架号");
        }
        carNo=carNo.substring(0,5);
        return acsService.TurnOriention(carNo, orientation);
    }

    //回库
    @ResponseBody
    @PostMapping("/getAvg")
//    @RequiresPermissions("task:agvMenuTask:add")
    @Log(title = "AGV", operating ="AGV回库", action = BusinessType.OTHER)
    public synchronized AjaxResult TaskAssignOne(Integer id , String goodsShelfNo, String row, String line, String station)
    {
        goodsShelfNo=goodsShelfNo.substring(0,5);
        station="ws0"+station;
        List<TaskDetail> taskDetails = taskHeaderService.selectList(goodsShelfNo,station);
        if(taskDetails.size()>0){
            return AjaxResult.error("还有任务没完成,无法回库");
        }
        AjaxResult ajaxResult=new AjaxResult();
        ajaxResult=acsService.TaskAssigns(id, goodsShelfNo, station,row,line);
        return ajaxResult;
    }

    /**
     *  手动叫车
     */
//    @RequiresPermissions("task:agvMenuTask:add")
    @Log(title = "AGV 任务下发", action = BusinessType.OTHER)
    @PostMapping("/ManualCalling")
    @ResponseBody
    public AjaxResult ManualCalling(String station,String shelfNo)
    {
        AjaxResult ajaxResult=null;
        try{
            station="ws0"+station;
            ajaxResult=acsService.ManualCalling(station,shelfNo);
        }catch (Exception e){
            ajaxResult=AjaxResult.error(e.getMessage());
        }
        return ajaxResult;
    }

}