package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base;

import cn.estsh.i3plus.ext.mes.pcn.api.base.IFirstOrderService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IPartExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IPackageExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesFirstOrderDetailRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesOrderJobRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesPackageExtRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesContainer;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @Author: xiangming.liao
 * @CreateDate: 2021/01/18 16:00
 * @Description:
 **/
@Slf4j
@Service
public class FirstOrderService implements IFirstOrderService {

    @Autowired
    private IPartExtService partExtService;

    @Autowired
    private IPackageExtService packageExtService;

    @Autowired
    private MesOrderJobRepository orderJobRepository;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private MesPackageExtRepository packageExtRepository;

    @Autowired
    private MesFirstOrderDetailRepository mesFirstOrderDetailRDao;

    @Autowired
    private MesContainerRepository containerRepository;

    @Override
    public void doCheckSerialNumber(String serialNumber, String orderNo, String workOrderNo, String organizeCode, String modifyUser) {
        if (StringUtils.isEmpty(serialNumber) || StringUtils.isEmpty(orderNo) ||
                StringUtils.isEmpty(workOrderNo) || StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(modifyUser)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("入参缺失必要参数")
                    .build();
        }

        MesOrderJob orderJobDb = orderJobRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), orderNo});
        if (null == orderJobDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("单据[%s]无效", orderNo)
                    .build();
        }

        if (!StringUtils.isEmpty(orderJobDb.getSerialNumber())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("单据[%s]已经绑定条码[%s],不可再次执行绑定", orderNo, orderJobDb.getSerialNumber())
                    .build();
        }

        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(organizeCode, workOrderNo);
        if (null == workOrderExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("生产工单号[%s]无效", workOrderNo)
                    .build();
        }

        MesPartExt partExt = partExtService.getPartExt(organizeCode, workOrderExt.getPartNo());
        if (null == partExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("生产工单号[%s]关联的物料编码[%s]无效", workOrderNo, workOrderExt.getPartNo())
                    .build();
        }

        if (StringUtils.isEmpty(partExt.getCategoryCode2()) || MesPcnExtEnumUtil.CATEGORY_CODE_2.OUTSIDE.getValue().equals(partExt.getCategoryCode2())) {

            MesOrderJob orderJobExist = orderJobRepository.getByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER},
                    new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber});
            if (null != orderJobExist) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("包装条码[%s]已经绑定单据[%s],不可再次执行绑定", serialNumber, orderJobExist.getOrderNo())
                        .build();
            }

            //扫描包装条码
            MesPackageExt packageExt = packageExtService.getPackageByPackNo(organizeCode, serialNumber);
            if (null == packageExt) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("包装条码[%s]无效", serialNumber)
                        .build();
            }

            if (StringUtils.isEmpty(partExt.getCategoryCode2())) {
                if (MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() != workOrderExt.getWorkOrderType()) {
                    if (!packageExt.getWorkOrderNo().equals(workOrderNo)) {
                        throw ImppExceptionBuilder.newInstance()
                                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                                .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                .setErrorDetail("生产工单[%s]未关联包装条码[%s]", workOrderNo, serialNumber)
                                .build();
                    } else {
                        if (!StringUtils.isEmpty(packageExt.getLastWorkOrderNo()) && !packageExt.getLastWorkOrderNo().equals(packageExt.getWorkOrderNo())) {
                            throw ImppExceptionBuilder.newInstance()
                                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                    .setErrorDetail("包装条码[%s]已经关联返工工单[%s]", serialNumber, packageExt.getLastWorkOrderNo())
                                    .build();
                        }
                    }
                } else {
                    if (StringUtils.isEmpty(packageExt.getLastWorkOrderNo()) || !packageExt.getLastWorkOrderNo().equals(workOrderNo)) {
                        throw ImppExceptionBuilder.newInstance()
                                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                                .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                .setErrorDetail("返工工单[%s]未关联包装条码[%s]", workOrderNo, serialNumber)
                                .build();
                    }
                }
            } else {
                if (!packageExt.getWorkOrderNo().equals(workOrderNo)) {
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("生产工单[%s]未关联包装条码[%s]", workOrderNo, serialNumber)
                            .build();
                }
            }
        } else {
            //扫描CT_NO
            MesContainer containerDb = containerRepository.getByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.CT_NO},
                    new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber});
            if (null == containerDb) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("容器条码[%s]无效", serialNumber)
                        .build();
            }

            if (MesPcnExtEnumUtil.CONTAINER_USE_STATUS.LEISURE.getValue() == containerDb.getUseStatus()) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("容器条码[%s]未进行生产,请重新扫描", serialNumber)
                        .build();
            }

            DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringEqualPack(serialNumber, MesPcnExtConstWords.CT_NO, packBean);
            DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesPcnExtConstWords.MODIFY_DATE_TIME}, packBean);
            MesPackageExt packageExt = packageExtRepository.getByProperty(packBean);
            if (null == packageExt) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("容器条码[%s]未关联包装条码", serialNumber)
                        .build();
            }
            if (!packageExt.getWorkOrderNo().equals(workOrderNo)) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("容器条码[%s]关联的最新包装条码[%s]对应的生产工单[%s]与当前生产工单[%s]不一致",
                                serialNumber, packageExt.getPackageNo(), packageExt.getWorkOrderNo(), workOrderNo)
                        .build();
            } else {
                if (!StringUtils.isEmpty(packageExt.getLastWorkOrderNo()) && !packageExt.getLastWorkOrderNo().equals(packageExt.getWorkOrderNo())) {
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("容器条码[%s]关联的包装条码[%s]已经关联返工工单[%s]", serialNumber, packageExt.getPackageNo(), packageExt.getLastWorkOrderNo())
                            .build();
                }
            }

            MesOrderJob orderJobExist = orderJobRepository.getByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER},
                    new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber});
            if (null != orderJobExist) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("容器条码[%s]已经绑定单据[%s],不可再次执行绑定", serialNumber, orderJobExist.getOrderNo())
                        .build();
            }

            serialNumber = packageExt.getPackageNo();
        }

        orderJobDb.setSerialNumber(serialNumber);
        ConvertBean.serviceModelUpdate(orderJobDb, modifyUser);
        orderJobRepository.save(orderJobDb);
    }

    @Override
    public List<MesFirstOrderDetail> findMesFirstOrderDetail(String orderNo, String organizeCode) {
        if(StringUtils.isEmpty(orderNo)){
            log.info("FirstOrderService-findMesFirstOrderDetail exec 单号为空 - 工厂代码：{}", organizeCode);
            return null;
        }
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(orderNo, "orderNo", packBean);
        packBean.setOrderByStr(" order by processCode ");
        return mesFirstOrderDetailRDao.findByHqlWhere(packBean);
    }

    @Override
    public void updateMesFirstOrderDetail(MesFirstOrderDetail mesFirstOrderDetail, String userName) {
        //根据单号查询任务主表信息
        String orderNo = mesFirstOrderDetail.getOrderNo();
        MesOrderJob mesOrderJob = orderJobRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, "orderNo"},
                new Object[]{mesFirstOrderDetail.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),
                        MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), orderNo});

        if(null == mesOrderJob){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("单据【%s】不存在",orderNo)
                    .build();
        }

        //修改首检单明细数据
        ConvertBean.serviceModelUpdate(mesFirstOrderDetail, userName);
        mesFirstOrderDetail.setSpotCheckTime(mesFirstOrderDetail.getModifyDatetime());
        mesFirstOrderDetail.setSpotCheckUser(userName);
        mesFirstOrderDetailRDao.save(mesFirstOrderDetail);

        mesOrderJob.setOrderStatus(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
        ConvertBean.serviceModelUpdate(mesOrderJob, userName);

        orderJobRepository.save(mesOrderJob);

    }
}
