package cn.estsh.i3plus.ext.mes.apiservice.controller.base.bu;

import cn.estsh.i3plus.ext.mes.api.base.bu.IBuWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesUnbindProduceSn;
import cn.estsh.i3plus.ext.mes.pojo.model.*;
import cn.estsh.i3plus.ext.mes.pojo.model.bu.MesOrderSeqModel;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.ExcelTool;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.model.RequestModel;
import cn.estsh.impp.framework.base.controller.MesBaseController;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(CommonConstWords.BASE_URL_MES + "/bu-ext/work-order")
@Api(tags = "松下bu生产工单")
public class BuWorkOrderExtController extends MesBaseController {

    @Autowired
    private IBuWorkOrderExtService workOrderExtService;

    @Autowired
    private ISxWorkOrderExtService sxWorkOrderExtService;

    @Resource(name="redisRes")
    private ImppRedis redisRes;
    @Autowired
    private EntityManager entityManager;

    @ApiOperation("生成工单")
    @PostMapping("generate")
    public ResultBean generateWorkOrder(@RequestBody GenerateWorkOrderDto workOrderDto){
        LOGGER.info("生成工单 输入参数 {}",workOrderDto);
        try {
            ValidatorBean.beginValid(workOrderDto)
                    .notNull("partNo",workOrderDto.getPartNo())
                    .notNull("partNameRdd",workOrderDto.getPartNameRdd())
                    .notNull("qty",workOrderDto.getQty())
                    .notNull("workCenterCode",workOrderDto.getWorkCenterCode())
                    .notNull("startTime",workOrderDto.getStartTime())
                    .notNull("endTime",workOrderDto.getEndTime());
            workOrderDto.setOrganizeCode(AuthUtil.getOrganize().getOrganizeCode());
            workOrderExtService.insertManualGenerate(workOrderDto);
            return ResultBean.success();
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }

    }

    /**
     * 系统检查导入的文件格式和数据必要性。文件格式错误提示“格式错误，请检查格式后再次导入。“。
     * 对物料编码、生产线代码和工厂做是否存在的判断，如果不存在，提示“[产线]***不存在“，[]内为数据字段，***为数据。
     * @param file 导入文件
     * @return
     */
    @ApiOperation("导入工单")
    @PostMapping("import")
    public ResultBean importWorkOrder(@RequestParam("file") MultipartFile file){
        try {
            ExcelTool excelTool =new ExcelTool(entityManager,redisRes).setThrowAllErrorMode(true);

            if(!file.getOriginalFilename().contains(".xlsx")){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                        .setErrorDetail("格式错误，请检查格式后再次导入")
                        .setErrorSolution("格式错误，请检查格式后再次导入")
                        .build();
            }
            List<ExcelWorkOrderDto> excelWorkOrderDtoList = excelTool.importData(file.getOriginalFilename(), file.getInputStream(), ExcelWorkOrderDto.class);
            workOrderExtService.importGenerate(excelWorkOrderDtoList);
            return ResultBean.success();
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }

    }

    @ApiOperation("调整工单")
    @PutMapping("adjust")
    public ResultBean adjustWorkOrder(@RequestBody GenerateWorkOrderDto generateWorkOrderDto){
        try {

            workOrderExtService.adjustWorkOrder(generateWorkOrderDto);
            return ResultBean.success();
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }


    @GetMapping(value = "/query-list-page")
    @ApiOperation(value = "生产工单分页查询")
    public ResultBean geWorkOrderListPage(WorkOrderQueryDto workOrderQueryDto, Pager pager) {
        try {

            // 生产工单分页列表
            return ResultBean.success("生产工单分页查询成功")
                    .setListPager(workOrderExtService.getWorkOrderListByPager(workOrderQueryDto, pager))
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException imppException) {
            LOGGER.error(imppException.getErrorMsg() + "：{}", imppException.getErrorDetail(), imppException);
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/update-order-status")
    @ApiOperation(value = "生产工单状态批量调整")
    public ResultBean updateWorkOrderStatus(@RequestBody RequestModel requestModel) {
        try {
            List<String> orderNoList = null;
            Integer workOrderStatus = null;
            if (null != requestModel) {
                orderNoList = requestModel.getOrderNoList();
                workOrderStatus = requestModel.getDestStatus();
            }
            // 数据校验
            ValidatorBean.checkNotNull(workOrderStatus, "工单状态不能为空");
            ValidatorBean.checkNotNull(orderNoList, "工单号不能为空");

            workOrderExtService.updateWorkOrderStatus(workOrderStatus, orderNoList);
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/find-by-seq")
    @ApiOperation(value = "查询需要排序的工单")
    public ResultBean findMesWorkOrderBySeqAsc(MesWorkOrder mesWorkOrder) {
        try {
            mesWorkOrder.setOrganizeCode(AuthUtil.getOrganize().getOrganizeCode());
            return new ResultBean(true, workOrderExtService.findMesWorkOrderBySeqAsc(mesWorkOrder)).setMsg("查询配置详情成功");
        } catch (ImppBusiException imppException) {
            LOGGER.error(imppException.getErrorMsg() + "：{}", imppException.getErrorDetail(), imppException);
            return ResultBean.fail(imppException);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/update-order-seq")
    @ApiOperation("生产工单调序-bu")
    public ResultBean updateOrderSeq(@RequestBody MesOrderSeqModel orderNoSeqModel){
        try {
            Long orderNo = orderNoSeqModel.getOrderNo();
            Long nextOrderNo = orderNoSeqModel.getNextOrderNo();
            String userName = AuthUtil.getSessionUser().getUserName();
            String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
            String workCenterCode = orderNoSeqModel.getWorkCenterCode();
            workOrderExtService.updateOrderSeq(orderNo,nextOrderNo,workCenterCode,organizeCode,userName);
            return ResultBean.success("调序成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }

    }

    @GetMapping("/get-production-batch")
    @ApiOperation("根据工单获取产量统计批次")
    public ResultBean getProductionBatchByWorkOrderNo(String workOrderNo){
        try {

            ValidatorBean.checkNotNull(workOrderNo, "工单号不能为空");

            Map<String, Object> productionBatchByWorkOrderNo = workOrderExtService.getProductionBatchByWorkOrderNo(workOrderNo, AuthUtil.getOrganize().getOrganizeCode());
            if (productionBatchByWorkOrderNo.get("flag").equals("success")) {
                return ResultBean.success("获取当前工单生产批次")
                        .setResultList((List) productionBatchByWorkOrderNo.get("content"))
                        .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
            } else {
                return ResultBean.fail(String.valueOf(productionBatchByWorkOrderNo.get("content")))
                        .setMsg(String.valueOf(productionBatchByWorkOrderNo.get("content")))
                        .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode());
            }

        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }

    }

    @PostMapping("/update-work-order-out-put-flag")
    @ApiOperation("修改是否使用完工数量 1是；2否")
    public ResultBean doUpdateWorkOrderIsUseCompleteQty(String workOrderNo, String workTime, String shiftCode, String outPutFlag) {
        try {

            ValidatorBean.checkNotNull(workOrderNo, "工单号不能为空");
            ValidatorBean.checkNotNull(outPutFlag, "是否使用完成数量不能为空");

            workOrderExtService.doUpdateWorkOrderIsUseCompleteQty(workOrderNo, workTime, shiftCode, outPutFlag, AuthUtil.getOrganize().getOrganizeCode(), AuthUtil.getSessionUser().getUserName());
            return ResultBean.success("修改成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }

    }

    @GetMapping(value = "/unbind-sn-query-pager")
    @ApiOperation(value = "分页查询解绑条码")
    public ResultBean queryUnbindSnByPager(MesUnbindProduceSn produceSn) {
        try {
            produceSn.setOrganizeCode(AuthUtil.getOrganize().getOrganizeCode());
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultList(workOrderExtService.queryMesUnbindSnList(produceSn));
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping(value = "/bind-unbind-sn")
    @ApiOperation(value = "绑定已解绑条码")
    public ResultBean doBindProduceSn(String produceSnList, String workOrderNo) {
        boolean flag = true;
        // 该redis 锁与 解绑条码绑定导入 一致
        String moduleKey = AuthUtil.getOrganize().getOrganizeCode() + ":MES_EXT_IMPORT_MODULE:" + MesExtEnumUtil.MES_EXT_EXCEL.MES_REWORK_ORDER_BIND_UNBIND_SN;
        try {
            if (!doLock(moduleKey)) {
                flag = false;
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("正在执行条码绑定，请稍后再试")
                        .build();
            }

            ValidatorBean.checkNotNull(produceSnList, "条码不能为空");
            ValidatorBean.checkNotNull(workOrderNo, "工单号不能为空");
            workOrderExtService.doBindUnbindSnByOrderNo(Arrays.asList(produceSnList.split(MesExtConstWords.COMMA)), workOrderNo, AuthUtil.getOrganize().getOrganizeCode(), AuthUtil.getSessionUser().getUserName());
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        } finally {
            if (flag) {
                redisMes.deleteKey(moduleKey);
            }
        }
    }

    private synchronized boolean doLock(String moduleKey) {
        if (redisMes.hasKey(moduleKey)) {
            return false;
        } else {
            redisMes.putObject(moduleKey, true, MesEnumUtil.EXPIRE_TIME.TEN_MIN.getValue());
            return true;
        }
    }

}
