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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IJobBookingService;
import cn.estsh.i3plus.ext.mes.pcn.icloud.sdk.IWmsJobBookingCloud;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOverModel;
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.mes.pcn.serviceimpl.base.BomService;
import cn.estsh.i3plus.mes.pcn.util.DateUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
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.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.base.util.StringUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesBom;
import cn.estsh.i3plus.pojo.mes.bean.MesContainer;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.MesBomRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
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.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yumingxing
 * @version 1.0
 * @date 2021/2/26 14:24
 **/
@Service
public class JobBookingService implements IJobBookingService {

    @Autowired
    BomService bomService;
    @Autowired
    private MesBomRepository bomRepository;
    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;
    @Autowired
    private MesContainerRepository containerRepository;
    @Autowired
    private MesPackageExtRepository packageExtRepository;
    @Autowired
    private ISyncFuncService syncFuncService;
    @Autowired
    private MesJobBookingPartRepository jobBookingPartRepository;
    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;
    @Autowired
    private MesContainerJobBookingRepository containerJobBookingRepository;
    @Autowired
    private IWmsJobBookingCloud iWmsJobBookingCloud;


    @Override
    public MesWorkOrderExt queryDefaultWorkOrder(String workCenterCode, String organizeCode) {
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (StringUtils.isEmpty(workCenterCode)) {
            return new MesWorkOrderExt();
        }
        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", ddlPackBean);
//        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue(), "workOrderType", ddlPackBean);
        List<Integer> statusList = new ArrayList<>();
//        statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());
        statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
//        statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
        DdlPreparedPack.getInPackList(statusList, "workOrderStatus", ddlPackBean);
//        DdlPreparedPack.timeBuilder(DateUtil.formatDate("yyyy-MM-dd", new Date()), DateUtil.formatDate("yyyy-MM-dd", new Date()), "createDatetime", ddlPackBean, true);
        List<MesWorkOrderExt> byHqlWhere = workOrderExtRepository.findByHqlWhere(ddlPackBean);
        byHqlWhere = byHqlWhere.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());
        return CollectionUtils.isEmpty(byHqlWhere) ? new MesWorkOrderExt() : byHqlWhere.get(0);
    }

    /**
     * 根据产线查询出为启动状态工单类型为返工工单,且seq最大的工单信息
     *
     * @param workCenterCode 工作中心代码
     * @return {@link MesWorkOrderExt}
     */
    @Override
    public ListPager<MesWorkOrderExt> queryWorkOrder(String workCenterCode, String organizeCode, String workOrderStatus, String partNo, String startTime, String endTime, Pager pager) {
        return getMesWorkOrderExt(workCenterCode, organizeCode, workOrderStatus, partNo, startTime, endTime, pager);
    }

    private ListPager<MesWorkOrderExt> getMesWorkOrderExt(String workCenterCode, String organizeCode, String workOrderStatus, String partNo, String startTime, String endTime, Pager pager) {
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);

        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", ddlPackBean);
//        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue(), "workOrderType", ddlPackBean);
        if (!StringUtils.isEmpty(workOrderStatus)) {
            DdlPreparedPack.getNumEqualPack(Integer.valueOf(workOrderStatus), "workOrderStatus", ddlPackBean);
        } else {
            List<Integer> statusList = new ArrayList<>();
            statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());
            statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
            statusList.add(MesPcnExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
            DdlPreparedPack.getInPackList(statusList, "workOrderStatus", ddlPackBean);
        }
        DdlPreparedPack.getStringLeftLikerPack(partNo, "partNo", ddlPackBean);
        DdlPreparedPack.timeBuilder(startTime, endTime, "createDatetime", ddlPackBean, true);
        List<MesWorkOrderExt> byHqlPage = workOrderExtRepository.findByHqlPage(ddlPackBean, pager);
        return new ListPager(byHqlPage, pager);
    }

    /**
     * 查询包装内容
     *
     * @param workCenterCode 工作中心代码
     * @param ctNo           容器编号
     * @return {@link MesPackageExt}
     */
    @Override
    public MesPackageExt queryContainerInfo(String workCenterCode, String ctNo, String partNo, String organizeCode) {
        //判断容器编号是否存在
        DdlPackBean conditionForPackageByCn = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(ctNo, "ctNo", conditionForPackageByCn);
        DdlPreparedPack.getNumEqualPack(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), "isSealed", conditionForPackageByCn);
        List<MesPackageExt> mesPackages = packageExtRepository.findByHqlWhere(conditionForPackageByCn);
        if (CollectionUtils.isEmpty(mesPackages)) {
            //如果容器编号不存在,可能是包装号packageNo,就根据packageNo查询
            DdlPackBean conditionForPackage = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringEqualPack(ctNo, "packageNo", conditionForPackage);
            MesPackageExt mesPackage = packageExtRepository.getByProperty(conditionForPackage);
            if (ObjectUtils.isEmpty(mesPackage)) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.CLOUD_CALL_EXCEPTION.getCode())
                        .setErrorDetail("容器编号或包装编号不存在")
                        .build();
            }
            return mesPackage;
        } else {
            mesPackages = mesPackages.stream().sorted(Comparator.comparing(MesPackageExt::getCreateDatetime).reversed()).collect(Collectors.toList());
            return mesPackages.get(0);
        }
    }

    @Override
    public void insertContainerJobBooking(MesPackageExt mesPackage) {
        MesContainerJobBooking containerJobBooking = new MesContainerJobBooking();
        BeanUtils.copyProperties(mesPackage, containerJobBooking, "id");
        containerJobBookingRepository.save(containerJobBooking);
    }

    private MesWorkCenterExt getWorkCenter(String workCenterCode, String organizeCode) {
        return workCenterExtRepository.getByProperty(
                new String[]{"workCenterCode", "organizeCode", "isValid", "isDeleted"},
                new Object[]{workCenterCode, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});
    }

    private String getPackage(String organizeCode) {
        String orderNo = "";
        BaseResultBean oneCodeResult = syncFuncService.syncSerialNo(new GenSerialNoModel(MesPcnExtConstWords.PACKAGE_NO), null, organizeCode, 1);
        if (oneCodeResult != null && oneCodeResult.isSuccess()) {
            orderNo = oneCodeResult.getResultList().get(0).toString();
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.CLOUD_CALL_EXCEPTION.getCode())
                    .setErrorDetail("生成包装编号失败")
                    .build();
        }
        return orderNo;
    }


    @Override
    public List<MesBom> queryPartBom(String partNo, String organizeCode) {
        if (StringUtil.isEmpty(partNo)) {
            return new ArrayList<>();
        }
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringLikerPack(partNo, "partNo", packBean);
        return this.bomRepository.findByHqlWhere(packBean);
    }


    @Override
    public MesJobBookingPart insertJobBookingPart(MesJobBookingPart detail) {
        return jobBookingPartRepository.save(detail);
    }

    @Override
    public void deleteJobBookingPart(long id) {
        jobBookingPartRepository.deleteById(id);
    }

    @Override
    public List<MesJobBookingPart> queryJobBookingPart(MesJobBookingPart detail) {

        if (StringUtil.isEmpty(detail.getPartNo())) {
            return new ArrayList<>();
        }
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(detail.getOrganizeCode());
        DdlPreparedPack.getStringLikerPack(detail.getPartNo(), "partNo", packBean);
        List<MesBom> mesBomList = this.bomRepository.findByHqlWhere(packBean);
        List<String> collect = mesBomList.stream().map(MesBom::getItemPartNo).collect(Collectors.toList());

        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(detail.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(detail.getOrderNo(), "orderNo", ddlPackBean);
        if (CollectionUtils.isEmpty(collect)) {
            DdlPreparedPack.getStringEqualPack(detail.getPartNo(), "partNo", ddlPackBean);
        } else {
            DdlPreparedPack.getInPackList(collect, "partNo", ddlPackBean);
        }

        DdlPreparedPack.getIsNull("setNo", ddlPackBean);
        return jobBookingPartRepository.findByHqlWhere(ddlPackBean);
    }

    @Override
    public void updateContainer(String workCenterCode, String ctNo, String partNo, String organizeCode) {
        MesContainer container = containerRepository.getByProperty("ctNo", ctNo);
        container.setUseStatus(String.valueOf(MesPcnEnumUtil.MES_CONTAINER_STATUS.OCCUPY.getValue()));
        containerRepository.update(container);
    }

    @Override
    public void doMesWorkOver(List<MesJobBookingPart> jobBookingParts, String userName, String organizeCode) {

        if (!CollectionUtils.isEmpty(jobBookingParts)) {

//            transformData
            List<MesWorkOverModel> workOverModelList = new ArrayList<>();
            for (MesJobBookingPart mesJobBookingPart : jobBookingParts) {
                MesWorkOverModel mesWorkOverModel = new MesWorkOverModel();
                mesWorkOverModel.setWorkOrderNo(mesJobBookingPart.getOrderNo());
                mesWorkOverModel.setItemPartNo(mesJobBookingPart.getPartNo());
                mesWorkOverModel.setItemPartName(mesJobBookingPart.getPartName());
                mesWorkOverModel.setQty(Integer.parseInt(mesJobBookingPart.getPartQty()));

                DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
                DdlPreparedPack.getStringEqualPack(mesJobBookingPart.getOrderNo(), "orderNo", workOrderCondition);
                MesWorkOrderExt mesWorkOrderExt = workOrderExtRepository.getByProperty(workOrderCondition);
                if (!ObjectUtils.isEmpty(mesWorkOrderExt)) {
                    mesWorkOverModel.setPdlineNo(mesWorkOrderExt.getWorkCenterCode());
                }
//                mesWorkOverModel.setItemUnit();
                workOverModelList.add(mesWorkOverModel);
            }
            iWmsJobBookingCloud.doMesWorkOver(workOverModelList, userName, organizeCode);
            String workOrderNo = workOverModelList.get(0).getWorkOrderNo();
            List<String> collect = workOverModelList.stream().map(MesWorkOverModel::getItemPartNo).distinct().collect(Collectors.toList());
            DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringEqualPack(workOrderNo, "orderNo", ddlPackBean);
            DdlPreparedPack.getInPack(collect, "partNo", ddlPackBean);
            jobBookingPartRepository.updateByProperties("setNo", UUID.randomUUID().toString(), ddlPackBean);
        }

    }
}
