package com.shkj.wms.controller.business;

import com.alibaba.druid.sql.ast.statement.SQLIfStatement;
import com.baomidou.lock.annotation.Lock4j;
import com.shkj.common.annotation.Log;
import com.shkj.common.annotation.RepeatSubmit;
import com.shkj.common.core.controller.BaseController;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.page.TableDataInfo;
import com.shkj.common.enums.BusinessType;
import com.shkj.common.utils.StringUtils;
import com.shkj.common.utils.poi.ExcelUtil;
import com.shkj.wms.bo.*;
import com.shkj.wms.common.IdEntity;
import com.shkj.wms.domain.BaseLocation;
import com.shkj.wms.domain.BusinOutInPlan;
import com.shkj.wms.enums.PlanStatusEnum;
import com.shkj.wms.enums.PlanTypeEnum;
import com.shkj.wms.service.IBusinOutInPlanService;
import com.shkj.wms.vo.BusinDataTaskVo;
import com.shkj.wms.vo.BusinOutInPlanVo;
import com.shkj.wms.vo.PlanOrderLocationVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 出入库计划
 *
 * @author lch
 * @menu 出入库计划管理
 * @date 2023-06-02
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@RequestMapping("/wms/plan")
public class BusinOutInPlanController extends BaseController {

    private final IBusinOutInPlanService iBusinOutInPlanService;

    /**
     * 查询出入库计划列表 type必传 默认为入库
     */
    @GetMapping("/list")
    public TableDataInfo<BusinOutInPlanVo> list(BusinOutInPlanQueryBo bo) {
        startPage();
        List arrType = new ArrayList();
       if(bo.getType().equals("in")) {
            arrType.add(PlanTypeEnum.IN.getValue());
            arrType.add(PlanTypeEnum.INPLAN.getValue());
            arrType.add(PlanTypeEnum.BACK.getValue());
           // arrType.add(PlanTypeEnum.BACK.getValue());
            bo.setArrType(arrType);
        }else if(bo.getType().equals("out")){
           arrType.add(PlanTypeEnum.OUT.getValue());
           arrType.add(PlanTypeEnum.OUTPLAN.getValue());
           bo.setArrType(arrType);
       }
       bo.setArrType(arrType);
        List<BusinOutInPlanVo> list = iBusinOutInPlanService.queryList(bo);
        return getDataTable(list);
    }

    /**
     * 导出出入库计划列表
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response, BusinOutInPlanQueryBo bo) {
        if (StringUtils.isBlank(bo.getType())) {
            bo.setType(PlanTypeEnum.IN.getValue());
        }
        List<BusinOutInPlanVo> list = iBusinOutInPlanService.queryList(bo);
        ExcelUtil<BusinOutInPlanVo> util = new ExcelUtil<BusinOutInPlanVo>(BusinOutInPlanVo.class);
        util.exportExcel(response, list, "任务数据");
    }


    /********************************入库相关接口******************************************/
    /**
     * 新增入库计划(模具入库)
     */
    @Log(title = "新增入库计划(模具入库)", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping("/addInPlan")
    public Result<Boolean> addInPlan(@Valid @RequestBody BusinInPlanAddBo bo) {
        return iBusinOutInPlanService.addInPlan(bo);
    }


    /**
     * 空托入库
     */
    @Log(title = "空托入库", businessType = BusinessType.INSERT)
    @PostMapping("/addInPlanByEmpty")
    public Result<Boolean> addInPlanByEmpty(@Valid @RequestBody List<BusinInPlanEmptyAddBo> bos) {
        return iBusinOutInPlanService.addInPlanByEmpty(bos);
    }


    /**
     * 新增入库计划(PC端新增入库计划)
     */
    @Log(title = "新增入库计划(PC端新增入库计划)", businessType = BusinessType.INSERT)
    @PostMapping("/addInPlanTime")
    public Result<Boolean> addInPlanTime(@Valid @RequestBody BusinInPlanTimeBo bo) {
        return iBusinOutInPlanService.addInPlanTime(bo);
    }

    /**
     * 呼叫空托盘
     */
    @Log(title = "呼叫空托盘", businessType = BusinessType.INSERT)
    @PostMapping("/callEmptyContainer")
    public Result<Boolean> callEmptyContainer() {
        return iBusinOutInPlanService.callEmptyContainer();
    }


    /**
     * 呼叫空托盘,根据模具的类型及可容纳新模具的数量
     */
    @Log(title = "呼叫空托盘", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/callEmptyContainerByQty")
    public Result<Boolean> callEmptyContainerByQty(@RequestBody BaseContainerCallBo bo) {
        return iBusinOutInPlanService.callEmptyContainerByQty(bo);
    }

    /********************************出库相关接口******************************************/

    /**
     * 待出库物料信息查询列表
     */
    @GetMapping("/waitOutPlan")
    public TableDataInfo<BusinOutInPlanVo> waitOutPlan(BusinOutInPlanQueryBo bo) {

        List arrType = new ArrayList();
        arrType.add(PlanTypeEnum.OUT.getValue());
        arrType.add(PlanTypeEnum.OUTPLAN.getValue());
        bo.setArrType(arrType);
        startPage();
        bo.setPlanStatus(PlanStatusEnum.DOING.getValue());
        List<BusinOutInPlanVo> list = iBusinOutInPlanService.queryList(bo);
        return getDataTable(list);
    }

    /**
     * 确认出库(前端也需要判断一下条码是否正确)
     */
    @Log(title = "确认出库", businessType = BusinessType.UPDATE)
    @PostMapping("/confirmOut")
    @RepeatSubmit()
    public Result<Boolean> confirmOut(@Valid @RequestBody List<BusinOutPlanConfirmBo> bos) {
        return iBusinOutInPlanService.confirmOut(bos);
    }


    /**
     * 下发出库任务
     */
    @Log(title = "下发出库任务", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/addOutPlan")
    public Result<Boolean> addOutPlan(@Valid @RequestBody BusinOutPlanAddBo bo) {
        return iBusinOutInPlanService.addOutPlan(bo);
    }

    /**
     * 新增出库计划
     */
    @Log(title = "下发出库任务", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/addOutPlanTime")
    public Result<Boolean> addOutPlanTime(@Valid @RequestBody BusinOutPlanAddBo bo) {
        return iBusinOutInPlanService.addOutPlanTime(bo);
    }


    /**
     * 取消入库计划
     */
    @Log(title = "取消入库计划", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/cancel")
    public Result<Boolean> cancel(@Valid @RequestBody IdEntity idEntity) {
        return iBusinOutInPlanService.cancel(idEntity.getId());
    }


    /**
     * 取消出入库计划
     */
    @Log(title = "取消出入库计划", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/outCancel")
    public Result<Boolean> outCancel(@Valid @RequestBody IdEntity idEntity) {
        return iBusinOutInPlanService.outCancel(idEntity.getId());
    }


    /**
     * 重新下发出库任务
     */
    @Log(title = "重新下发出库任务", businessType = BusinessType.UPDATE)
    @PostMapping("/repeatOutStock")
    public Result<Boolean> repeatOutStock(@Valid @RequestBody UpdPlanStatusCallbackBo bo) throws InterruptedException {
        return iBusinOutInPlanService.repeatOutStock(bo.getOrderNo());
    }

    /************************************wcs交互接口******************************************************/

    /**
     * 根据托盘编号来查询计划的编号(如果没有的话就是新增回库任务)
     */
    @GetMapping("/wcsGetOrderNoByContainerCode")
    public Result<PlanOrderLocationVo> wcsGetOrderNoByContainerCode(String containerCode, @RequestParam(required = false) String planType) {
        return iBusinOutInPlanService.getOrderNoByContainerCode(containerCode, planType);
    }

    /**
     * 根据订单编号，获取入库或出库的库位信息
     */
    @GetMapping("/wcsGetLocationByOrderNo")
    public Result<BaseLocation> wcsGetLocationByOrderNo(String orderNo) {
        return iBusinOutInPlanService.wcsGetLocationByOrderNo(orderNo);
    }

    /**
     * 根据订单编号，查询下计划类型
     */
    @GetMapping("/wcsGetPlanByOrderNo")
    public Result<BusinOutInPlan> wcsGetPlanByOrderNo(String orderNo) {
        return iBusinOutInPlanService.wcsGetPlanByOrderNo(orderNo);
    }

    /**
     * 更新任务状态
     */
    @Log(title = "更新任务状态", businessType = BusinessType.UPDATE)
    @PostMapping("/updPlanStatus")
    public Result<Boolean> updPlanStatus(@Valid @RequestBody UpdPlanStatusCallbackBo bo) {
        return iBusinOutInPlanService.updPlanStatus(bo.getOrderNo(), bo.getPlanStatus());
    }

    /**
     * 入库失败清空预库存
     */
    @Log(title = "入库失败清空预库存", businessType = BusinessType.UPDATE)
    @PostMapping("/updateSysStockByPlanOrderNo")
    public Result<Boolean> updateSysStockByPlanOrderNo(@Valid @RequestBody UpdPlanStatusCallbackBo bo) {
        return Result.ok().data(iBusinOutInPlanService.updateSysStockByPlanOrderNo(bo.getOrderNo().toString()));
    }



    /**
     * 根据任务编号更新异常信息
     */
    @Log(title = "根据任务编号更新异常信息", businessType = BusinessType.UPDATE)
    @PostMapping("/updErrMsg")
    public Result<Boolean> updErrMsg(@Valid @RequestBody UpdPlanErrorBo bo) {
        return iBusinOutInPlanService.updErrMsg(bo);
    }

    /**
     * 根据任务编号重新分配高货位
     */
    @Log(title = "根据任务编号重新分配高货位", businessType = BusinessType.UPDATE)
    @PostMapping("/repeatFindHighLocation")
    public Result<Boolean> repeatFindHighLocation(@Valid @RequestBody UpdPlanLocationBo bo) {
        return iBusinOutInPlanService.repeatFindHighLocation(bo);
    }


    /**
     * 测试回库计划
     */
    @Log(title = "测试回库计划", businessType = BusinessType.UPDATE)
    @PostMapping("/testOut")
    public Result<PlanOrderLocationVo> testOut(@Valid @RequestParam String barcodeValue) {
        return iBusinOutInPlanService.getOrderNoByContainerCode(barcodeValue, "in");
    }


    /**
     * 测试回库计划，如果是出库回库时，并且有模具，报警时需要清理库存
     */
    @Log(title = "测试回库计划", businessType = BusinessType.UPDATE)
    @PostMapping("/updateSysStockByPlanOrderN2")
    public Boolean updateSysStockByPlanOrderNo2(@Valid @RequestParam String orderNo) {
        return iBusinOutInPlanService.updateSysStockByPlanOrderNo(orderNo);
    }




    /**
     * 获取正在执行中的任务信息（入库）
     */
    @Log(title = "获取正在执行中的任务信息（入库）", businessType = BusinessType.UPDATE)
    @GetMapping("/getTaskInfo")
    public TableDataInfo<BusinDataTaskVo> getTaskInfo(BusinTaskQueryBo bo) {
        startPage();
        List<BusinDataTaskVo> list = iBusinOutInPlanService.getTaskInfo(bo);
        return getDataTable(list);
    }
}
