package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.jx;

import cn.estsh.i3plus.ext.mes.pcn.api.base.ICheckErrorLogService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IWorkOrderStartService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
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.MesWorkCell;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @author yumingxing
 * @version 1.0
 * @date 2021/2/19 16:06
 **/
@Slf4j
@Service
public class TorqueManageCheckService implements IWorkOrderStartService {

    @Autowired
    private ICheckErrorLogService checkErrorLogService;

    @Autowired
    private MesProcessTorqueManageRepository torqueManageRepository;

    @Autowired
    private MesProcessTorqueManageTaskDetailRepository torqueManageTaskDetailRepository;

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;

    @Autowired
    private MesWorkCellRepository workCellRepository;

    @Autowired
    private MesProcessCellRepository processCellRepository;

    @Autowired
    private MesOrderJobRepository orderJobRepository;

    @Autowired
    private MesOrderRuleRepository orderRuleRepository;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Resource(name = MesPcnExtConstWords.REDIS_RES_PCN)
    private ImppRedis redisMesPcn;

    /**
     * 工单启动后方法执行
     *
     * @param workOrderExt 工单
     * @return {@link ResultBean}
     */
    @Override
    public void doGenCheckOrder(MesWorkOrderExt workOrderExt, String userInfo) {
        MesCheckErrorLog checkErrorLog = new MesCheckErrorLog();
        checkErrorLog.setGenerationMethod(MesPcnExtEnumUtil.GENERATION_METHOD.FROM_WORK_ORDER_START.getValue());
        checkErrorLog.setGeneratingModule(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getDescription());

        String msg;
        try {

            MesWorkCenterExt workCenterExt = workCenterExtRepository.getByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.WORK_CENTER_CODE},
                    new Object[]{workOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), workOrderExt.getWorkCenterCode()});

            if (null == workCenterExt) {
                msg = String.format("扭矩管理生成单据:工单[%s]生产线[%s]无效", workOrderExt.getOrderNo(), workOrderExt.getWorkCenterCode());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }
            if (StringUtils.isEmpty(workCenterExt.getShiftCode()) || StringUtils.isEmpty(workCenterExt.getWorkTime())) {
                msg = String.format("扭矩管理生成单据:工单[%s]生产线[%s]未启动班次", workOrderExt.getOrderNo(), workOrderExt.getWorkCenterCode());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }

            if (checkGenedOrder(workOrderExt, userInfo, checkErrorLog, workCenterExt)) return;

            //1、查找产线下所有的工位
            List<MesWorkCell> mesWorkCellList = workCellRepository.findByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                    new Object[]{workOrderExt.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), workOrderExt.getWorkCenterCode()});

            //2、通过产线和工位去工序工位关系表中查询所有的工序
            List<String> workCells = mesWorkCellList.stream().map(MesWorkCell::getWorkCellCode).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(workCells)) {
                msg = String.format("扭矩管理生成单据:工单[%s]生产线[%s]未关联工位", workOrderExt.getOrderNo(), workOrderExt.getWorkCenterCode());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }

            DdlPackBean pcPackBean = MesHqlPack.getMesAllData(workOrderExt.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(workOrderExt.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, pcPackBean);
            DdlPreparedPack.getInPackList(workCells, MesPcnExtConstWords.WORK_CELL_CODE, pcPackBean);
            List<MesProcessCell> processCellList = processCellRepository.findByHqlWhere(pcPackBean);
            if (CollectionUtils.isEmpty(processCellList)) {
                msg = String.format("扭矩管理生成单据:工单[%s]请先维护工序工位关系", workOrderExt.getOrderNo());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }

            //DdlPackBean torqueManageTaskDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode);
            //DdlPreparedPack.getStringEqualPack(orderNo, MesPcnExtConstWords.ORDER_NO, torqueManageTaskDetailPackBean);
            //List<MesProcessTorqueManageTaskDetail> torqueManageTaskDetailList =  torqueManageTaskDetailRepository.findByHqlWhere(torqueManageTaskDetailPackBean);
            //if (!CollectionUtils.isEmpty(torqueManageTaskDetailList)) {
            //    msg = String.format("扭矩管理点检生成单据:工单[%s]已经生成过扭矩管理点检单", workOrderExt.getOrderNo());
            //    log.info(msg);
            //    checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
            //    return;
            //}

            //DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(workOrderExt.getOrganizeCode());
            //DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getValue(), MesPcnExtConstWords.ORDER_TYPE, ddlPackBean);
            //DdlPreparedPack.getStringEqualPack(workOrderExt.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, ddlPackBean);
            //DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_CREATE_RULE.WORK_ORDER_CREATE.getValue(), MesPcnExtConstWords.CREATE_RULE, ddlPackBean);
            DdlPackBean caseCondition = DdlPackBean.getDdlPackBean(workOrderExt.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(workOrderExt.getPartNo(), MesPcnExtConstWords.PART_NO, caseCondition);
            List<MesProcessTorqueManage> torqueManageList = torqueManageRepository.findByHqlWhere(caseCondition);
            if (CollectionUtils.isEmpty(torqueManageList)) {
                msg = String.format("扭矩管理点检生成单据:工单[%s]物料编码[%s]未维护扭矩管理点检基础数据", workOrderExt.getOrderNo(), workOrderExt.getPartNo());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }

            List<MesOrderRule> orderRuleList = orderRuleRepository.findByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED,
                            MesPcnExtConstWords.ORDER_TYPE, MesPcnExtConstWords.CREATE_RULE, MesPcnExtConstWords.WORK_CENTER_CODE},
                    new Object[]{workOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),
                            MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getValue(), MesPcnExtEnumUtil.MES_OR_CREATE_RULE.WORK_ORDER_CREATE.getValue(), workOrderExt.getWorkCenterCode()});
            Optional<MesOrderRule> orderRuleOp = CollectionUtils.isEmpty(orderRuleList) ? null :
                    orderRuleList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getShiftCode()) && o.getShiftCode().equals(workCenterExt.getShiftCode()))).findFirst();
            if (null == orderRuleOp || !orderRuleOp.isPresent()) {
                orderRuleOp = CollectionUtils.isEmpty(orderRuleList) ? null : orderRuleList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getShiftCode()))).findFirst();
            }
            if (null == orderRuleOp || !orderRuleOp.isPresent()) {
                msg = String.format("扭矩管理点检生成单据:工单[%s]未配置生产线代码[%s][工单创建][扭矩管理点检]班次为[%s]或班次为空的单据规则信息,请检查", workOrderExt.getOrderNo(), workOrderExt.getWorkCenterCode(), workCenterExt.getShiftCode());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }

            MesOrderJob mesOrderJob = new MesOrderJob();
            mesOrderJob.setTaskType(orderRuleOp.get().getTaskType());
            mesOrderJob.setOrderType(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getValue());
            List<String> orderNoList = getOrderNoByRuleCode(1, MesPcnExtConstWords.ORDER_NO_RULE, new GenSerialNoModel(), userInfo, workOrderExt.getOrganizeCode());
            if (CollectionUtils.isEmpty(orderNoList)) {
                msg = String.format("扭矩管理点检生成单据:工单[%s]单据编号未生成成功", workOrderExt.getOrderNo());
                log.info(msg);
                checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
                return;
            }
            mesOrderJob.setOrderNo(orderNoList.get(0));
            mesOrderJob.setWorkCenterCode(workOrderExt.getWorkCenterCode());
            mesOrderJob.setShiftCode(workCenterExt.getShiftCode());
            mesOrderJob.setWorkOrderNo(workOrderExt.getOrderNo());
            mesOrderJob.setOrderStatus(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
            mesOrderJob.setOrderDate(TimeTool.getToday());
            mesOrderJob.setWorkTime(workCenterExt.getWorkTime());
            mesOrderJob.setOrganizeCode(workOrderExt.getOrganizeCode());
            ConvertBean.serviceModelInitialize(mesOrderJob, userInfo);
            mesOrderJob.setGenerateTime(mesOrderJob.getModifyDatetime());
            orderJobRepository.insert(mesOrderJob);

            for (MesProcessTorqueManage torqueManage : torqueManageList) {
                //通过工序和产线查询工序工位信息
                DdlPackBean pcPackBeanByPrcs = MesHqlPack.getMesAllData(workOrderExt.getOrganizeCode());
                DdlPreparedPack.getStringEqualPack(torqueManage.getProcessCode(), MesPcnExtConstWords.PROCESS_CODE, pcPackBeanByPrcs);
                DdlPreparedPack.getStringEqualPack(mesOrderJob.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, pcPackBeanByPrcs);
                MesProcessCell processCell = processCellRepository.getByProperty(pcPackBeanByPrcs);
                if(null != processCell){
                    MesProcessTorqueManageTaskDetail detail = new MesProcessTorqueManageTaskDetail();
                    BeanUtils.copyProperties(torqueManage, detail, MesPcnExtConstWords.ID);
                    detail.setOrderJobNo(mesOrderJob.getOrderNo());
                    detail.setWorkCenterCode(mesOrderJob.getWorkCenterCode());
                    detail.setWorkCenterName(processCell.getWorkCenterName());
                    detail.setWorkOrderNo(mesOrderJob.getWorkOrderNo());
                    detail.setShiftCode(workCenterExt.getShiftCode());
                    detail.setWorkCellCode(processCell.getWorkCellCode());
                    detail.setWorkCellName(processCell.getWorkCellName());
                    detail.setProcessCode(processCell.getProcessCode());
                    detail.setProcessName(processCell.getProcessName());
                    detail.setPartNo(workOrderExt.getPartNo());
                    detail.setPartName(workOrderExt.getPartNameRdd());
                    detail.setOrganizeCode(workOrderExt.getOrganizeCode());
                    detail.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());

                    ConvertBean.serviceModelInitialize(detail, userInfo);
                    torqueManageTaskDetailRepository.insert(detail);
                }
            }
        } catch (Exception e) {
            checkErrorLogService.insertCheckErrorLog(checkErrorLog, e.getMessage(), userInfo);
            log.info(e.getMessage());
        }
    }

    private boolean checkGenedOrder(MesWorkOrderExt workOrderExt, String userInfo, MesCheckErrorLog checkErrorLog, MesWorkCenterExt workCenterExt) {

        String msg;

        StringJoiner key = new StringJoiner(MesPcnExtConstWords.COLON).add("MES-PAUSE-ORDER").add(workOrderExt.getOrderNo());

        String workCenterWoPauseKey = new StringJoiner(MesPcnExtConstWords.COLON).add("MES-PAUSE-ORDER").add(workOrderExt.getWorkCenterCode()).toString();

        //String workOrderNo = (String) redisMesPcn.getObject(workCenterWoPauseKey);
        //
        //String pauseOrderKey = (String) redisMesPcn.getObject(key);

        //if (StringUtils.isEmpty(pauseOrderKey)) {
        //    msg = String.format("扭矩管理点检生成单据:工单[%s]在一分钟内有过暂停操作，操作频繁，等待一分钟后可再生成扭矩管理点检单", workOrderExt.getOrderNo());
        //    log.info(msg);
        //    checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
        //    return true;
        //}
        //
        //if (!StringUtils.isEmpty(workOrderNo) && workOrderNo.equals(workOrderExt.getOrderNo())) {
        //
        //    DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrderExt.getOrganizeCode());
        //    DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getValue(), MesPcnExtConstWords.ORDER_TYPE, packBean);
        //    DdlPreparedPack.getStringEqualPack(workOrderExt.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        //    DdlPreparedPack.getStringEqualPack(workCenterExt.getShiftCode(), MesPcnExtConstWords.SHIFT_CODE, packBean);
        //    DdlPreparedPack.getStringEqualPack(workCenterExt.getWorkTime(), MesPcnExtConstWords.WORK_TIME, packBean);
        //    DdlPreparedPack.getStringEqualPack(workOrderExt.getOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        //    List<MesOrderJob> orderJobList = orderJobRepository.findByHqlWhere(packBean);
        //
        //    if (!CollectionUtils.isEmpty(orderJobList)) {
        //        msg = String.format("扭矩管理点检生成单据:工单[%s]已经生成过扭矩管理点检单", workOrderExt.getOrderNo());
        //        log.info(msg);
        //        checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
        //        return true;
        //    }
        //}

        //DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrderExt.getOrganizeCode());
        //DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.TORQUE_MANAGE.getValue(), MesPcnExtConstWords.ORDER_TYPE, packBean);
        //DdlPreparedPack.getStringEqualPack(workOrderExt.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        //DdlPreparedPack.getStringEqualPack(workCenterExt.getShiftCode(), MesPcnExtConstWords.SHIFT_CODE, packBean);
        //DdlPreparedPack.getStringEqualPack(workCenterExt.getWorkTime(), MesPcnExtConstWords.WORK_TIME, packBean);
        //DdlPreparedPack.getStringEqualPack(workOrderExt.getOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        //List<MesOrderJob> orderJobList = orderJobRepository.findByHqlWhere(packBean);
        //
        //if (!CollectionUtils.isEmpty(orderJobList)) {
        //    msg = String.format("扭矩管理点检生成单据:工单[%s]已经生成过扭矩管理点检单", workOrderExt.getOrderNo());
        //    log.info(msg);
        //    checkErrorLogService.insertCheckErrorLog(checkErrorLog, msg, userInfo);
        //    return true;
        //}
        return false;
    }

    private List<String> getOrderNoByRuleCode(int number, String ruleCode, GenSerialNoModel genSerialNoModel, String userName, String org) {
        genSerialNoModel.setRuleCode(ruleCode);
        BaseResultBean<String> serialNumberBean;
        try {
            serialNumberBean = syncFuncService.syncSerialNo(genSerialNoModel, userName, org, Integer.valueOf(number));
        } catch (Exception e) {
            return null;
        }
        if (serialNumberBean != null && serialNumberBean.isSuccess()) {
            return serialNumberBean.getResultList();
        } else {
            return null;
        }
    }
}
