package com.ruoyi.web.controller.business;

import java.math.BigDecimal;
import java.util.*;

import com.ruoyi.business.domain.*;
import com.ruoyi.business.service.*;
import com.ruoyi.business.utils.OrderCodeFactory;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.web.service.DictService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * Mes出库任务控制类
 *
 * @author liangzhou
 * @date 2022-09-29
 */
@Controller
@RequestMapping("/business/mesManage")
public class MesTaskManageController extends BaseController {
    private String prefix = "business/mesManage";

    @Autowired
    private ITConveyorStatusService tConveyorStatusService;

    @Autowired
    private ITCkPickingwavegoodsService tCkPickingwavegoodsService;

    @Autowired
    private ITConveyorStatusService itConveyorStatusService;

    @Autowired
    private ITCkOrderdetailService tCkOrderdetailService;

    @Autowired
    private ITMiStockService tMiStockService;

    @Autowired
    private IVehicleService vehicleService;

    @Autowired
    private IOrderManageService orderManageService;

    @Autowired
    private ITCkPicktaskService tCkPicktaskService;

    @Autowired
    private DictService dict;

    /**
     * 工单出库界面
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:orderTask:view")
    @GetMapping("/orderTaskOut")
    public String orderTaskOut(ModelMap mmap) {
        // 获取当前用户
        SysUser sysUser = ShiroUtils.getCurrentUser();

        TConveyorStatus tConveyorStatus = new TConveyorStatus();
        // 用户登录IP
        tConveyorStatus.setPcip(ShiroUtils.getIp());
        sysUser.setLoginIp(ShiroUtils.getIp());

        List<TConveyorStatus> tConveyorStatusList = itConveyorStatusService.selectTConveyorStatusList(tConveyorStatus);
        if (tConveyorStatusList != null && tConveyorStatusList.size() > 0) {
            tConveyorStatus = tConveyorStatusList.get(0);
            // 获取用户登录的站台号
            sysUser.setOutStand(tConveyorStatus.getConveryorId());
        }
        mmap.put("sysUser", sysUser);
        mmap.put("orderManage", new OrderManage());
        return prefix + "/orderTaskOut";
    }

    /**
     * 工单出库界面详情
     */
    @RequiresPermissions("business:orderTask:list")
    @PostMapping("/orderTaskOut/main")
    @ResponseBody
    public TableDataInfo taskOutMain(TCkPickingwavegoods tCkPickingwavegoods) {
        startPage();
        List<TCkPickingwavegoods> list = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(tCkPickingwavegoods);
        return getDataTable(list);
    }

    /**
     * 工单出库任务执行
     */
    @RequiresPermissions("business:orderTask:add")
    @Log(title = "工单出库", businessType = BusinessType.INSERT)
    @PostMapping("/orderTaskOut/updateTask")
    @ResponseBody
    public AjaxResult updateTask(TCkOrderdetail tCkOrderdetail) {
        // 检查当前站台是否有正在出库的任务
        TCkPickingwavegoods tCkPickingwavegoods = new TCkPickingwavegoods();
        tCkPickingwavegoods.setOutstand(tCkOrderdetail.getOutStand());
        List<TCkPickingwavegoods> outTaskList = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(tCkPickingwavegoods);
        if (outTaskList.size() > 0) {
            return success("-2");
        }

        // 更新（未选择则默认选择第一条）
        OrderManage orderManageForSel = new OrderManage();
        orderManageForSel.setGoodsId(tCkOrderdetail.getGoodId());
        orderManageForSel.setStatus("0");
        List<OrderManage> mesTaskList = orderManageService.selectOrderListForOut(orderManageForSel);
        if (mesTaskList.size() < 0) {
            // 返回无任务
            return success("-3");
        }

        // start 检查当前库存是否充足(只查合格品)
        TMiStock tMiStock = new TMiStock();
        tMiStock.setGoodsId(mesTaskList.get(0).getGoodsId());
        tMiStock.setSts("0");
        List<TMiStock> list = tMiStockService.selectTMiStockOutList(tMiStock);
        if (list.size() > 0) {
            if (list.get(0).getShelvesNum().compareTo(mesTaskList.get(0).getWaitNum()) >= 0) {// 库存充足
                TCkOrderdetail tCkOrderdetailForOut = new TCkOrderdetail();
                tCkOrderdetailForOut.setGoodId(mesTaskList.get(0).getGoodsId());
                tCkOrderdetailForOut.setOutStand(tCkOrderdetail.getOutStand());
                tCkOrderdetailForOut.setPickNum(mesTaskList.get(0).getWaitNum());
                tCkOrderdetailForOut.setCkId(OrderCodeFactory.getOrderCode("CK", ""));
                tCkOrderdetailForOut.setCkType("4");
                tCkOrderdetailForOut.setStatus("0");
                tCkOrderdetailForOut.setAddtime(new Date());
                // 用户名为MES
                tCkOrderdetailForOut.setUserName("MES");
                return toAjax(tCkOrderdetailService.insertTCkOrderdetail(tCkOrderdetailForOut));
            } else {// 库存不足
                return success("0");
            }
        }
        // end 检查当前库存是否充足
        return success("-1");
    }

    /**
     * 工单拣选
     */
    @RequiresPermissions("business:orderTask:add")
    @Log(title = "工单拣选出库", businessType = BusinessType.INSERT)
    @PostMapping("/orderTaskOut/checkOut")
    @ResponseBody
    public AjaxResult orderCheckOut(TCkPickingwavegoods tCkPickingwavegoods) {
        // 查询当前操作工单
        OrderManage orderManageForUpdate = orderManageService.selectOrderManageByOrderId(tCkPickingwavegoods.getOutId());
        // 插入任务成功，同时更新当前的工单信息，并且导出下一条待出库工单
        if (orderManageForUpdate.getWaitNum().compareTo(tCkPickingwavegoods.getPickingNum()) < 0) {// 发料数量不够
            // 更新已发数量
            orderManageForUpdate.setFinishNum(orderManageForUpdate.getFinishNum().add(tCkPickingwavegoods.getPickingNum()));
            // 更新待发数量
            orderManageForUpdate.setWaitNum(orderManageForUpdate.getWaitNum().subtract(tCkPickingwavegoods.getPickingNum()));
            // 更新当前出库任务信息为可回库
            tCkPickingwavegoods.setOutstatus("3");
            List<TCkPickingwavegoods> waitForScanTaskList = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(tCkPickingwavegoods);
            if (waitForScanTaskList.size() < 1) {
                return error("0");
            }
            TCkPickingwavegoods scanTask = waitForScanTaskList.get(0);
            scanTask.setOutstatus("4");
            if (tCkPickingwavegoodsService.updateScanGoodsResult(scanTask) < 1) {
                return error("-2");
            }
        } else {
            // 更新已发数量
            orderManageForUpdate.setFinishNum(orderManageForUpdate.getNeedNum());
            // 更新待发数量
            orderManageForUpdate.setWaitNum(BigDecimal.ZERO);
            // 状态置为完成
            orderManageForUpdate.setStatus("1");
            // 插入任务
            if (!createPickTask(tCkPickingwavegoods)) {
                return error("-2");
            }
        }
        if (orderManageService.updateOrderManage(orderManageForUpdate) > 0) {
            // 获取下一条工单
            return success(orderManageService.selectNextOrder(tCkPickingwavegoods.getGoodId()));
        } else {
            // 更新当前出库任务信息为可回库
            tCkPickingwavegoods.setOutstatus("3");
            List<TCkPickingwavegoods> waitForScanTaskList = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(tCkPickingwavegoods);
            if (waitForScanTaskList.size() < 1) {
                return error("0");
            }
            TCkPickingwavegoods scanTask = waitForScanTaskList.get(0);
            scanTask.setOutstatus("4");
            if (tCkPickingwavegoodsService.updateScanGoodsResult(scanTask) < 1) {
                return error("-2");
            }
        }

        return success();
    }

    /**
     * 结束本次发料
     */
    @RequiresPermissions("business:orderTask:add")
    @Log(title = "结束本次发料", businessType = BusinessType.INSERT)
    @PostMapping("/orderTaskOut/endGoodsOut")
    @ResponseBody
    public AjaxResult endGoodsOut(TCkPickingwavegoods tCkPickingwavegoods) {
        // 更新当前出库任务信息为可回库
        tCkPickingwavegoods.setOutstatus("3");
        List<TCkPickingwavegoods> waitForScanTaskList = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(tCkPickingwavegoods);
        if (waitForScanTaskList.size() < 1) {
            return success("0");
        }
        TCkPickingwavegoods scanTask = waitForScanTaskList.get(0);
        scanTask.setOutstatus("4");
        if (tCkPickingwavegoodsService.updateScanGoodsResult(scanTask) < 1) {
            return success("-2");
        }
        return success("1");
    }

    /**
     * 生成一个工单任务
     *
     * @param tCkPickingwavegoods
     * @return
     */
    private boolean createPickTask(TCkPickingwavegoods tCkPickingwavegoods) {
        TCkPicktask tCkPicktask = new TCkPicktask();
        // 任务号
        tCkPicktask.setTaskid(OrderCodeFactory.getOrderCode("CK", ""));
        // 任务类型
        tCkPicktask.setTaskType(2);
        // 起始站台号
        tCkPicktask.setOrigin(Objects.equals(tCkPickingwavegoods.getOutstand(), "1001") ? "306" : "406");
        // 托盘号
        Vehicle vehicle_sel = new Vehicle();
        vehicle_sel.setStandId(Objects.equals(tCkPickingwavegoods.getOutstand(), "1001") ? "305" : "405");
        vehicle_sel.setStatus("0");
        List<Vehicle> vehicleSelList = vehicleService.selectVehicleList(vehicle_sel);
        if (vehicleSelList.size() < 1) {
            return false;
        }
        tCkPicktask.setVesselNo(vehicleSelList.get(0).getVehicleId());
        // 任务状态
        tCkPicktask.setTaskStatus(0);
        // 创建时间
        tCkPicktask.setCreateTime(new Date());
        // 工单
        tCkPicktask.setWipentity(tCkPickingwavegoods.getCustomermemberid());
        // 物料编码
        tCkPicktask.setGoodsId(tCkPickingwavegoods.getGoodId());
        // 数量
        tCkPicktask.setGoodsNum(tCkPickingwavegoods.getPickingNum());
        // 批次号
        tCkPicktask.setBatchNo(tCkPickingwavegoods.getProduclotid());

        return tCkPicktaskService.insertTCkPicktask(tCkPicktask) > 0;
    }

    /**
     * 弹框表格
     */
    @GetMapping("/orderTaskOut/pickingTask")
    public String pickingTask() {
        return prefix + "/pickingTask";
    }

    /**
     * 查询工单出库任务列表
     */
    @RequiresPermissions("business:orderTask:list")
    @PostMapping("/orderTaskOut/query")
    @ResponseBody
    public TableDataInfo pickingTaskQuery(OrderManage orderManage) {
        startPage();
        List<OrderManage> list = orderManageService.selectOrderListForOut(orderManage);
        return getDataTable(list);
    }

    /**
     * 工单管理界面
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:orderTaskManage:view")
    @GetMapping("/orderTaskManage")
    public String orderTaskManage(ModelMap mmap) {
        mmap.put("orderManage", new OrderManage());
        return prefix + "/orderTaskManage";
    }

    /**
     * 工单管理界面详情
     */
    @RequiresPermissions("business:orderTaskManage:list")
    @PostMapping("/orderTaskManage/main")
    @ResponseBody
    public TableDataInfo taskMain(OrderManage orderManage) {
        startPage();
        List<OrderManage> list = orderManageService.selectOrderManageList(orderManage);
        return getDataTable(list);
    }

    /**
     * 更改工单顺序
     */
    @RequiresPermissions("business:orderTaskManage:update")
    @Log(title = "更改工单顺序", businessType = BusinessType.UPDATE)
    @PostMapping("/orderTaskManage/reorder")
    @ResponseBody
    public AjaxResult reorder(OrderManage orderManage) {
        // 查询需要调整的工单
        OrderManage orM = orderManageService.selectOrderManageList(orderManage).get(0);
        // 查询上一条工单
        OrderManage preOrder = orderManageService.selectPreOrder(orM);
        // 更新顺序
        orderManage.setSortIndex(preOrder.getSortIndex());
        return success(orderManageService.upOneOrder(orderManage) > 0 ? "1" : "0");
    }

    /**
     * 工单取消
     *
     * @param orderIds
     * @return
     */
    @Log(title = "工单取消", businessType = BusinessType.UPDATE)
    @RequiresPermissions("business:orderTaskManage:cancel")
    @PostMapping("/orderTaskManage/cancelOrder")
    @ResponseBody
    public AjaxResult cancelOrder(String orderIds) {
        // 取消工单
        if (orderManageService.cancelOrdersByOrderIds(orderIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 载具A界面
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:vehicle:view")
    @GetMapping("/vehicleA")
    public String vehicleA(ModelMap mmap) {
        // 站台状态---是否启用
        String switchA = "1";
        TConveyorStatus status = new TConveyorStatus();
        status.setConveryorId("1001");
        List<TConveyorStatus> tConveyorStatuses = tConveyorStatusService.selectTConveyorStatusList(status);
        if(tConveyorStatuses != null && tConveyorStatuses.size() > 0) {
            switchA = tConveyorStatuses.get(0).getMovests();
        }
        mmap.put("switchA", switchA);
        mmap.put("vehicleA", new Vehicle());
        return prefix + "/vehicleA";
    }

    /**
     * 查询载具A的详情
     */
    @RequiresPermissions("business:vehicle:list")
    @PostMapping("/vehicleA/vehicleInfo")
    @ResponseBody
    public TableDataInfo vehicleAInfo(Vehicle vehicleA) {
        startPage();
        vehicleA.setStandId("A");
        List<Vehicle> list = vehicleService.selectVehicleList(vehicleA);
        return getDataTable(list);
    }

    /**
     * 载具A更改状态为已出库
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "更改载具状态", businessType = BusinessType.UPDATE)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleA/checkOut")
    @ResponseBody
    public AjaxResult checkOutA(String vehicleIds) {
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 取消此条agv任务，同时重新下发一条agv取载具的命令
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "呼叫AGV工单出库", businessType = BusinessType.INSERT)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleA/callAgvOut")
    @ResponseBody
    public AjaxResult callAgvOutA(String vehicleIds) {
        // TODO: 2022/11/7 具体实现未确定
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 呼叫AGV取空载具
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "呼叫AGV取空载具", businessType = BusinessType.INSERT)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleA/callAgvTakeEmpty")
    @ResponseBody
    public AjaxResult callAgvTakeEmptyA(String vehicleIds) {
        // TODO: 2022/11/7 具体实现未确定
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 载具B界面
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:vehicle:view")
    @GetMapping("/vehicleB")
    public String vehicleB(ModelMap mmap) {
        // 站台状态---是否启用
        String switchB = "1";
        TConveyorStatus status = new TConveyorStatus();
        status.setConveryorId("1002");
        List<TConveyorStatus> tConveyorStatuses = tConveyorStatusService.selectTConveyorStatusList(status);
        if(tConveyorStatuses != null && tConveyorStatuses.size() > 0) {
            switchB = tConveyorStatuses.get(0).getMovests();
        }
        mmap.put("switchB", switchB);
        mmap.put("vehicleB", new Vehicle());
        return prefix + "/vehicleB";
    }

    /**
     * 查询载具B的详情
     */
    @RequiresPermissions("business:vehicle:list")
    @PostMapping("/vehicleB/vehicleInfo")
    @ResponseBody
    public TableDataInfo vehicleBInfo(Vehicle vehicleB) {
        startPage();
        vehicleB.setStandId("B");
        List<Vehicle> list = vehicleService.selectVehicleList(vehicleB);
        return getDataTable(list);
    }

    /**
     * 载具B更改状态为已出库
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "更改载具状态", businessType = BusinessType.INSERT)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleB/checkOut")
    @ResponseBody
    public AjaxResult checkOutB(String vehicleIds) {
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 取消此条agv任务，同时重新下发一条agv取载具的命令
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "呼叫AGV工单出库", businessType = BusinessType.INSERT)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleB/callAgvOut")
    @ResponseBody
    public AjaxResult callAgvOutB(String vehicleIds) {
        // TODO: 2022/11/7 具体实现未确定
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 呼叫AGV取空载具
     *
     * @param vehicleIds
     * @return
     */
    @Log(title = "呼叫AGV取空载具", businessType = BusinessType.INSERT)
    @RequiresPermissions("business:vehicle:update")
    @PostMapping("/vehicleB/callAgvTakeEmpty")
    @ResponseBody
    public AjaxResult callAgvTakeEmptyB(String vehicleIds) {
        // TODO: 2022/11/7 具体实现未确定
        // 更改载具状态
        if (vehicleService.updateVehicleStsByVehicleIds(vehicleIds) > 0) {
            return success();
        }
        return error();
    }

    /**
     * 回库
     */
    @Log(title = "返库", businessType = BusinessType.UPDATE)
    @PostMapping("/backStock")
    @ResponseBody
    public AjaxResult backStock(TCkPickingwavegoods tCkPickingwavegoods) {
        TCkPickingwavegoods forSel = new TCkPickingwavegoods();
        forSel.setOutstand(tCkPickingwavegoods.getOutstand());
        forSel.setOutstatus("4");
        List<TCkPickingwavegoods> waitForBackTaskList = tCkPickingwavegoodsService.selectTCkPickingwavegoodsList(forSel);
        if (waitForBackTaskList.size() < 1) {
            return success("0");
        }
        TCkPickingwavegoods backTask = waitForBackTaskList.get(0);
        backTask.setOutstatus("2");
        // 更新实际拣货数量
        backTask.setPickingNum(tCkPickingwavegoods.getPickingNum());
        return toAjax(tCkPickingwavegoodsService.updateGoodsOutResult(backTask));
    }
}
