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

import cn.estsh.i3plus.ext.mes.api.busi.jx.IJxWorkOrderService;
import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.AntiStaticCheckModel;
import cn.estsh.i3plus.ext.mes.pojo.model.jx.JxReworkSnModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @PROJECT_NAME: i3plus-mes-panasonic-jx
 * @DESCRIPTION:
 * @USER: xinwang.yi
 * @DATE: 2023-10-30 15:44
 */
@Service
public class JxWorkOrderService implements IJxWorkOrderService {

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private MesWorkOrderRepository workOrderRepository;

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;
    
    @Autowired
    private MesProduceSnRepairRepository produceSnRepairRepository;

    @Autowired
    private MesSubassemblyRemadeRecordRepository subassemblyRemadeRecordRepository;

    // 产品条码
    public static final Integer PRODUCT_SN_TYPE = 10;
    // 包装条码
    public static final Integer PACKAGE_SN_TYPE = 20;

    @Override
    public void deleteSnRepairByType(String workOrderNo, String[] snArr, String organizeCode, String userName) {

        MesWorkCenterExt workCenterExt = getMesWorkCenterExt4WorkOrderNo(workOrderNo);

        if (workCenterExt.getLineType().equals(String.valueOf(MesExtEnumUtil.LINE_TYPE.ONTOLOGY_LINE.getValue()))) {
            // 本体
            deleteProduceSnRepair(workOrderNo, snArr, organizeCode, userName);
        } else {
            // 组件
            deletePackageNoRepair(workOrderNo, snArr, organizeCode, userName);
        }
    }

    @Override
    public void deleteProduceSnRepair(String workOrderNo, String[] produceSnArr, String organizeCode, String userName) {

        DdlPackBean packBean =  DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workOrderNo, MesExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getInPackArray(produceSnArr, MesExtConstWords.PRODUCT_SN, packBean);
        List<MesProduceSnRepair> produceSnRepairList = produceSnRepairRepository.findByHqlWhere(packBean);

        Map<String, MesProduceSnRepair> produceSnRepairListByPs = produceSnRepairList.stream().collect(Collectors.toMap(MesProduceSnRepair::getProductSn, Function.identity(), (x, y) -> y));

        if (CollectionUtils.isEmpty(produceSnRepairList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("返工条码不存在")
                    .build();
        }

        String nowTime = TimeTool.getNowTime(true);

        updateProduceSn(produceSnArr, produceSnRepairListByPs, organizeCode, userName, nowTime);

        for (MesProduceSnRepair produceSnRepair : produceSnRepairList) {
            produceSnRepair.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            produceSnRepair.setModifyUser(userName);
            produceSnRepair.setModifyDatetime(nowTime);
            produceSnRepair.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        }

        produceSnRepairRepository.saveAll(produceSnRepairList);

    }

    @Override
    public void deletePackageNoRepair(String workOrderNo, String[] packageNoArr, String organizeCode, String userName) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackArray(packageNoArr, MesExtConstWords.PACKAGENO, packBean);
        DdlPreparedPack.getStringEqualPack(workOrderNo, MesExtConstWords.WORK_ORDER_NO, packBean);
        List<MesSubassemblyRemadeRecord> subassemblyRemadeRecordList = subassemblyRemadeRecordRepository.findByHqlWhere(packBean);

        if (CollectionUtils.isEmpty(subassemblyRemadeRecordList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("返工条码不存在")
                    .build();
        }

        for (MesSubassemblyRemadeRecord subassemblyRemadeRecord : subassemblyRemadeRecordList) {
            subassemblyRemadeRecord.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            ConvertBean.serviceModelUpdate(subassemblyRemadeRecord, userName);
            subassemblyRemadeRecord.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        }

        subassemblyRemadeRecordRepository.saveAll(subassemblyRemadeRecordList);
    }

    @Override
    public ListPager queryRepairSnByPager(String workOrderNo, String sn, String organizeCode, Pager pager) {

        MesWorkCenterExt workCenterExt = getMesWorkCenterExt4WorkOrderNo(workOrderNo);

        if (workCenterExt.getLineType().equals(String.valueOf(MesExtEnumUtil.LINE_TYPE.ONTOLOGY_LINE.getValue()))) {

            // 本体
            return queryRepairProduceSnByPager(workOrderNo, sn, organizeCode, pager);

        } else {

            // 组件
            return queryRepairPackageByPager(workOrderNo, sn, organizeCode, pager);

        }
    }

    private MesWorkCenterExt getMesWorkCenterExt4WorkOrderNo(String workOrderNo) {
        MesWorkOrderExt workOrderExt = workOrderExtRepository.getByProperty(
                new String[]{MesExtConstWords.ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID},
                new Object[]{workOrderNo, AuthUtil.getOrganize().getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()});

        if (workOrderExt == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工单[%s]不存在", workOrderNo)
                    .build();
        }

        if (StringUtils.isEmpty(workOrderExt.getWorkCenterCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("工单[%s]未维护产线")
                    .build();
        }

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

        if (workCenterExt == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("产线[%s]不存在", workOrderExt.getWorkCenterCode())
                    .build();
        }
        return workCenterExt;
    }

    @Override
    public ListPager queryRepairPackageByPager(String workOrderNo, String packageNo, String organizeCode, Pager pager) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workOrderNo, MesExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getStringEqualPack(packageNo, MesExtConstWords.PACKAGENO, packBean);
        pager = PagerHelper.getPager(pager, subassemblyRemadeRecordRepository.findByHqlWhereCount(packBean));
        packBean.setOrderByStr(" order by modifyDatetime desc ");
        List<MesSubassemblyRemadeRecord> subassemblyRemadeRecordList = subassemblyRemadeRecordRepository.findByHqlWherePage(packBean, pager);

        List<JxReworkSnModel> jxReworkSnModels = new ArrayList<>();

        for (MesSubassemblyRemadeRecord subassemblyRemadeRecord : subassemblyRemadeRecordList) {
            JxReworkSnModel jxReworkSnModel = new JxReworkSnModel();
            jxReworkSnModel.setWorkOrderNo(workOrderNo);
            jxReworkSnModel.setSn(subassemblyRemadeRecord.getPackageNo());
            jxReworkSnModels.add(jxReworkSnModel);
        }

        return new ListPager(jxReworkSnModels, pager);
    }

    @Override
    public ListPager queryRepairProduceSnByPager(String workOrderNo, String sn, String organizeCode, Pager pager) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workOrderNo, MesExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getStringEqualPack(sn, MesExtConstWords.PRODUCT_SN, packBean);
        pager = PagerHelper.getPager(pager, produceSnRepairRepository.findByHqlWhereCount(packBean));
        packBean.setOrderByStr(" order by modifyDatetime desc ");
        List<MesProduceSnRepair> produceSnRepairList = produceSnRepairRepository.findByHqlWherePage(packBean, pager);
        List<JxReworkSnModel> jxReworkSnModels = new ArrayList<>();

        for (MesProduceSnRepair produceSnRepair : produceSnRepairList) {
            JxReworkSnModel jxReworkSnModel = new JxReworkSnModel();
            jxReworkSnModel.setWorkOrderNo(workOrderNo);
            jxReworkSnModel.setSn(produceSnRepair.getProductSn());
            jxReworkSnModels.add(jxReworkSnModel);
        }

        return new ListPager(jxReworkSnModels, pager);
    }

    private void updateProduceSn(String[] productSnArr, Map<String, MesProduceSnRepair> produceSnRepairListByPs,
                                        String organizeCode, String userName, String nowTime) {
        DdlPackBean packBean1 = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackArray(productSnArr, MesExtConstWords.PRODUCT_SN, packBean1);
        List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByHqlWhere(packBean1);

        for (MesProduceSnExt produceSnExt : produceSnExtList) {
            if (produceSnRepairListByPs.containsKey(produceSnExt.getProductSn())) {
                produceSnExt.setLastWorkOrderNo(produceSnRepairListByPs.get(produceSnExt.getProductSn()).getInitWorkOrderNo());
                produceSnExt.setModifyUser(userName);
                produceSnExt.setModifyUserExt(userName);
                produceSnExt.setModifyDatetime(nowTime);
                produceSnExt.setModifyUserExt(nowTime);
                produceSnExt.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue());
                produceSnExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                produceSnExt.setSystemSyncStatusExt(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            } else {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("返工条码[%s]不存在", produceSnExt.getProductSn())
                        .build();
            }
        }

        produceSnExtRepository.saveAll(produceSnExtList);
    }

    @Override
    public List<MesWorkOrder> queryWorkOrderListByModifyDatetime(MesWorkOrder workOrder) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrder.getOrganizeCode());
        DdlPreparedPack.timeBuilder(workOrder.getModifyDateTimeStart(), workOrder.getModifyDateTimeEnd(), MesExtConstWords.MODIFY_DATE_TIME, packBean, true);
        return workOrderRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesWorkOrder> queryMesWorkOrderByOrderNoList(List<String> workOrderNoList, String organizeCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(workOrderNoList, MesExtConstWords.ORDER_NO, packBean);
        return workOrderRepository.findByHqlWhere(packBean);
    }
}
