package cn.estsh.i3plus.ext.mes.pcn.apiservice.controller.busi;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IOqcManageService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesOqcCheckDetail;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MissPartConfirmModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.OqcLastCheckModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.OqcLastCheckParamModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.OqcManageModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.impp.framework.base.controller.MesPcnBaseController;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
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.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @Author: wangjie
 * @CreateDate: 2021/01/19 15:37
 * @Description:
 **/
@RestController
@RequestMapping(CommonConstWords.BASE_URL_MES_PCN)
@Api(tags = "出货检验")
public class OqcManageController extends MesPcnBaseController {

    @Autowired
    private IOqcManageService oqcManageService;

    @PostMapping("/oqc-manage/query")
    @ApiOperation(value = "出货检验查询")
    public ResultBean queryOqcData(@RequestBody OqcManageModel model) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_ID, model.getUserId());
            OqcManageModel result = oqcManageService.queryOqcData(model);
            return ResultBean.success(StringUtils.isEmpty(result.getMsg()) ? "查询成功" : result.getMsg()).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultObject(result);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/detail")
    @ApiOperation(value = "出货检验明细")
    public ResultBean queryOqcDetail(String organizeCode, String oqcNo, Pager pager) {
        try {
            return ResultBean.success("查询成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setListPager(oqcManageService.queryOqcDetail(organizeCode, oqcNo, pager));
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/reload")
    @ApiOperation(value = "重载检验项")
    public ResultBean doOqcDetailReload(@RequestBody OqcManageModel model) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_INFO, model.getUserInfo())
                    .notNull(MesPcnExtConstWords.WORK_ORDER_NO, model.getWorkOrderNo())
                    .notNull(MesPcnExtConstWords.PART_NO, model.getPartNo())
                    .notNull(MesPcnExtConstWords.OQC_TYPE, model.getOqcType())
                    .notNull(MesPcnExtConstWords.OQC_NO, model.getOqcNo());
            oqcManageService.doOqcDetailReload(model);
            return ResultBean.success("查询成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/change")
    @ApiOperation(value = "切换")
    public ResultBean changeOqcData(@RequestBody OqcManageModel model) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_ID, model.getUserId())
                    .notNull(MesPcnExtConstWords.WORK_ORDER_NO, model.getWorkOrderNo())
                    .notNull(MesPcnExtConstWords.PART_NO, model.getPartNo())
                    .notNull(MesPcnExtConstWords.WORK_CENTER_CODE, model.getWorkCenterCode())
                    .notNull(MesPcnExtConstWords.SHIFT_CODE, model.getShiftCode())
                    .notNull(MesPcnExtConstWords.WORK_TIME, model.getWorkTime())
                    .notNull(MesPcnExtConstWords.OQC_NO, model.getOqcNo());
            return ResultBean.success("切换成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultObject(oqcManageService.changeOqcData(model));
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/reset")
    @ApiOperation(value = "重置")
    public ResultBean resetOqcData(@RequestBody OqcManageModel model) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_ID, model.getUserId());
            return ResultBean.success("重置成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultObject(oqcManageService.resetOqcData(model));
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/insert")
    @ApiOperation(value = "生成检验单")
    public ResultBean insertOqcData(@RequestBody OqcManageModel model) {
        String key = new StringJoiner(MesPcnExtConstWords.COLON)
                .add(model.getOrganizeCode()).add(MesPcnExtConstWords.OQC_MANAGE_LOCK).add(model.getWorkCenterCode()).add(model.getWorkOrderNo()).toString();
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_INFO, model.getUserInfo())
                    .notNull(MesPcnExtConstWords.USER_ID, model.getUserId())
                    .notNull(MesPcnExtConstWords.WORK_ORDER_NO, model.getWorkOrderNo())
                    .notNull(MesPcnExtConstWords.WORK_ORDER_TYPE, model.getWorkOrderType())
                    .notNull(MesPcnExtConstWords.PART_NO, model.getPartNo())
                    .notNull(MesPcnExtConstWords.WORK_CENTER_CODE, model.getWorkCenterCode())
                    .notNull(MesPcnExtConstWords.SHIFT_CODE, model.getShiftCode())
                    .notNull(MesPcnExtConstWords.WORK_TIME, model.getWorkTime())
                    .notNull(MesPcnExtConstWords.SPOT_CHECK_QTY, model.getSpotCheckQty())
                    .notNull(MesPcnExtConstWords.BATCH_LIMIT, model.getBatchLimit())
                    .notNull(MesPcnExtConstWords.OQC_TYPE, model.getOqcType());

            if (!doLock(key)) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("生成检验单:此刻有用户正在操作工单[%s]的出货检验,请稍后重试", model.getWorkOrderNo())
                        .build();
            }

            oqcManageService.insertOqcData(model);
            return ResultBean.success("生成成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        } finally {
            redisMesPcn.deleteKey(key);
        }
    }

    private synchronized boolean doLock(String key) {
        if (redisMesPcn.hasKey(key)) {
            return false;
        } else {
            redisMesPcn.putObject(key, true, MesPcnEnumUtil.EXPIRE_TIME.ONE_MIN.getValue());
            return true;
        }
    }

    @PostMapping("/oqc-manage/detail-update")
    @ApiOperation(value = "修改检验项")
    public ResultBean updateOqcDetail(@RequestBody MesOqcCheckDetail oqcCheckDetail) {
        try {
            ValidatorBean.beginValid(oqcCheckDetail)
                    .notNull(MesPcnExtConstWords.ID, oqcCheckDetail.getId())
                    .notNull(MesPcnExtConstWords.MODIFY_USER, oqcCheckDetail.getModifyUser());
            oqcManageService.updateOqcDetail(oqcCheckDetail);
            return ResultBean.success("修改成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-manage/oqc-check-update")
    @ApiOperation(value = "修改检验单结果")
    public ResultBean updateOqcCheck(@RequestBody OqcManageModel model) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_INFO, model.getUserInfo())
                    .notNull(MesPcnExtConstWords.CHECK_RESULT, model.getCheckResult())
                    .notNull(MesPcnExtConstWords.OQC_NO, model.getOqcNo());
            oqcManageService.updateOqcCheck(model);
            return ResultBean.success("修改成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping("/oqc-last-check/query-pager")
    @ApiOperation(value = "总检验结果分页查询")
    public ResultBean queryOqcLastCheckPager(OqcLastCheckModel model, Pager pager) {
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode());
            ListPager listPager = oqcManageService.queryOqcLastCheckPager(model, pager);
            return ResultBean.success("查询成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setListPager(listPager).setResultObject(new OqcLastCheckModel(CollectionUtils.isEmpty(listPager.getObjectList())));
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/oqc-last-check/update")
    @ApiOperation(value = "修改总检验单结果")
    public ResultBean updateOutPutStatisticsOqcCheck(@RequestBody OqcLastCheckParamModel model) {
        Map<String, String> workOrderNoList = CollectionUtils.isEmpty(model.getModelList()) ? null :
                model.getModelList().stream()
                        .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkOrderNo()) && !StringUtils.isEmpty(o.getWorkCenterCode()) && !StringUtils.isEmpty(o.getOrganizeCode())))
                        .collect(Collectors.toMap(OqcLastCheckParamModel::getWorkOrderNo, o -> new StringJoiner(MesPcnExtConstWords.COLON)
                                .add(o.getOrganizeCode()).add(MesPcnExtConstWords.OQC_MANAGE_LOCK).add(o.getWorkCenterCode()).add(o.getWorkOrderNo()).toString()));
        List<String> keyList = new ArrayList<>();
        try {
            ValidatorBean.beginValid(model)
                    .notNull(MesPcnExtConstWords.ORGANIZE_CODE, model.getOrganizeCode())
                    .notNull(MesPcnExtConstWords.USER_INFO, model.getUserInfo());
            if (CollectionUtils.isEmpty(model.getModelList())) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("总检验单结果:入参错误")
                        .build();
            }

            for (String workOrderNo : workOrderNoList.keySet()) {
                if (!StringUtils.isEmpty(workOrderNo)) {
                    if (!doLock(workOrderNoList.get(workOrderNo))) {
                        throw ImppExceptionBuilder.newInstance()
                                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                                .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                .setErrorDetail("生成检验单:此刻有用户正在操作工单[%s]的出货检验,请稍后重试", workOrderNo)
                                .build();
                    }
                    keyList.add(workOrderNoList.get(workOrderNo));
                }
            }
            oqcManageService.updateOutPutStatisticsOqcCheck(model);
            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 (!CollectionUtils.isEmpty(keyList)) {
                for (String key : keyList) {
                    redisMesPcn.deleteKey(key);
                }
            }
        }
    }

    @GetMapping("/oqc-project-check/total-miss-part")
    @ApiOperation(value = "查询缺件信息")
    public ResultBean queryMissingPart(String serialNumber, String organizeCode, Pager pager) {
        try {
            MissPartConfirmModel missPartConfirm = oqcManageService.queryMissingPart(serialNumber, organizeCode, pager);
            return ResultBean.success("查询成功").setResultObject(missPartConfirm)
                    .setListPager(missPartConfirm.getMesErrorLineOffs())
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping("/oqc-project-check/update-error-line")
    @ApiOperation(value = "确认合格")
    public ResultBean updateErrorLineOff(Long[] idsStr, String organizeCode, String userInfo) {
        try {
            oqcManageService.updateErrorLineOff(idsStr, organizeCode, userInfo);
            return ResultBean.success("修改成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

}
