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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesPartCheckDetailService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxPcnHttpService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IWorkCenterExtService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.IPartCheckDao;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesOrderJob;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesPartCheckDetail;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.PartCheckDetailModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.WmsSnInfoModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesOrderJobRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesPartCheckDetailRepository;
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.util.PcnHttpUtil;
import cn.estsh.i3plus.mes.pcn.util.StringUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
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.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.MesWorkCell;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * @Author: xiangming.liao
 * @CreateDate: 2021/01/18 11:41 上午
 * @Description:
 **/
@Slf4j
@Service
@Transactional(readOnly = false)
public class MesPartCheckDetailService implements IMesPartCheckDetailService {
    @Autowired
    private MesPartCheckDetailRepository mesPartCheckDetailRDao;
    @Autowired
    private MesOrderJobRepository mesOrderJobRDao;
    @Autowired
    private IPartCheckDao partCheckDao;
    @Autowired
    private ISxPcnHttpService pcnHttpService;
    @Autowired
    private IWorkCenterExtService workCenterExtService;


    @Override
    public List<MesPartCheckDetail> updateOrderStatusCheck(MesPartCheckDetail detail) throws IOException {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        String userName = AuthUtil.getSessionUser().getUserName();
        String itemPartNo = detail.getItemPartNo();
        if (StringUtil.isEmpty(itemPartNo)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请扫描条码信息")
                    .build();
        }
        String workCellCode = detail.getWorkCellCode();
        if (StringUtil.isEmpty(workCellCode)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请选择工位")
                    .build();
        }
        List<MesPartCheckDetail> partCheckDetailList = getMesPartCheckDetails(detail);
        //List<MesPartCheckDetail> partCheckDetailList = mesPartCheckDetailRDao.findByProperty(new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO, MesPcnExtConstWords.ITEM_PART_NO},
        //        new Object[]{detail.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), detail.getOrderNo(), detail.getItemPartNo()});
        if (CollectionUtils.isEmpty(partCheckDetailList)) {
            String requestUrl = pcnHttpService.getRequestUrl(organizeCode, MesPcnExtConstWords.FIND_PART_NO);
            Map<String, String> params = new HashMap<>();
            params.put(MesPcnExtConstWords.SN, detail.getItemPartNo());
            params.put(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode);
            String data = PcnHttpUtil.doGet(requestUrl, params);
            BaseResultBean baseResultBean = null;
            WmsSnInfoModel wmsSnInfoModel = null;
            if (!StringUtils.isEmpty(data)) {
                baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
            } else {
                log.error("HTTP[{}]调用主接口失败", requestUrl);
            }
            if (null != baseResultBean && baseResultBean.success) {
                LinkedHashMap resultObject = (LinkedHashMap) baseResultBean.getResultObject();
                wmsSnInfoModel= JsonUtilTool.decode(JSONObject.toJSONString(resultObject), WmsSnInfoModel.class);
            }
            if(wmsSnInfoModel==null){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("无法获取此条码信息")
                        .build();
            }
            detail.setItemPartNo(wmsSnInfoModel.getPartNo());
            partCheckDetailList = getMesPartCheckDetails(detail);
        }
        partCheckDetailList.forEach(pcd -> {
            if (pcd.getOrderStatus() == MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue()
                    || pcd.getOrderStatus() == MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue()
            ) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("该条码已扫描，不能重复扫描")
                        .build();
            }

            //修改单据主表状态为点检中
            MesOrderJob mesOrderJob = mesOrderJobRDao.getByProperty(
                    new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO},
                    new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),
                            MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), pcd.getOrderNo()});
            String nowTime = TimeTool.getNowTime(true);
            if (mesOrderJob.getOrderStatus() == MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue()) {
                mesOrderJob.setOrderStatus(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
                mesOrderJob.setComplateTime(nowTime);
                ConvertBean.saveOrUpdate(mesOrderJob, userName);
                mesOrderJobRDao.save(mesOrderJob);
            }
            mesPartCheckDetailRDao.updateByProperties(new String[]{MesPcnExtConstWords.ID}, new Object[]{pcd.getId()},
                    new String[]{MesPcnExtConstWords.ORDER_STATUS, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.COMPLATE_TIME,MesPcnExtConstWords.CHECK_TIME,MesPcnExtConstWords.CHECK_USER},
                    new Object[]{MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue(), userName, nowTime, nowTime, nowTime, userName});
        });

        //如果全部明细点检完成，则orderJob修改为点检完成
        updateOrderJobCheckComplete(detail);

        return partCheckDetailList;
    }

    /**
     * 获得物料点检明细
     * @param detail
     * @return
     */
    private List<MesPartCheckDetail> getMesPartCheckDetails(MesPartCheckDetail detail) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(detail.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(detail.getOrderNo(), MesPcnExtConstWords.ORDER_NO, packBean);
        DdlPreparedPack.getStringEqualPack(detail.getItemPartNo(), MesPcnExtConstWords.ITEM_PART_NO, packBean);
        DdlPreparedPack.getStringEqualPack(detail.getWorkCellCode(), MesPcnExtConstWords.WORK_CELL_CODE, packBean);
        List<MesPartCheckDetail> partCheckDetailList = mesPartCheckDetailRDao.findByHqlWhere(packBean);
        return partCheckDetailList;
    }

    /**
     * 修改单据作业状态为点检完成
     * @param detail
     */
    private void updateOrderJobCheckComplete(MesPartCheckDetail detail) {
        DdlPackBean isCheckPackBean = DdlPackBean.getDdlPackBean(detail.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(detail.getOrderNo(), MesPcnExtConstWords.ORDER_NO, isCheckPackBean);
        List<Integer> orderStatusList = new ArrayList<>();
        orderStatusList.add(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
        orderStatusList.add(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
        DdlPreparedPack.getInPackList(orderStatusList, MesPcnExtConstWords.ORDER_STATUS, isCheckPackBean);
        List<MesPartCheckDetail> isCheckDetailList = mesPartCheckDetailRDao.findByHqlWhere(isCheckPackBean);
        if (CollectionUtils.isEmpty(isCheckDetailList)) {
            String nowTime = TimeTool.getNowTime(true);
            mesOrderJobRDao.updateByProperties(new String[]{MesPcnExtConstWords.ORDER_NO}, new Object[]{detail.getOrderNo()},
                    new String[]{MesPcnExtConstWords.ORDER_STATUS, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.COMPLATE_TIME},
                    new Object[]{MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue(), AuthUtil.getSessionUser().getUserName(), nowTime, nowTime});
        }
    }

    @Override
    public int partCheckSubmit(String orderNo, String organizeCode, String modifyUser) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(orderNo, MesPcnExtConstWords.ORDER_NO, packBean);
        List<Integer> orderStatusList = new ArrayList<>();
        orderStatusList.add(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
        orderStatusList.add(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
        DdlPreparedPack.getInPackList(orderStatusList, MesPcnExtConstWords.ORDER_STATUS, packBean);
        List<MesPartCheckDetail> partCheckDetailList = mesPartCheckDetailRDao.findByHqlWhere(packBean);
        if (!CollectionUtils.isEmpty(partCheckDetailList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请完成所有点检项")
                    .build();
        }
        return mesOrderJobRDao.updateByProperties(new String[]{MesPcnExtConstWords.ORDER_NO}, new Object[]{orderNo},
                new String[]{MesPcnExtConstWords.ORDER_STATUS, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.COMPLATE_TIME},
                new Object[]{MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue(), modifyUser, TimeTool.getNowTime(true), TimeTool.getNowTime(true)});
    }

    @Override
    public List<MesWorkCell> queryCellByOrderNo(String orderNo, String organizeCode) {
        //根据业务只会是查询一条生产线的工位
        List<MesWorkCell> workCellList = null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(orderNo, MesPcnExtConstWords.ORDER_NO, packBean);
        List<MesPartCheckDetail> partCheckDetailList = mesPartCheckDetailRDao.findByHqlWhere(packBean);
        partCheckDetailList = CollectionUtils.isEmpty(partCheckDetailList) ? null :
                partCheckDetailList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCenterCode()) && !StringUtils.isEmpty(o.getWorkCellCode()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(partCheckDetailList)) {
            return workCellList;
        }
        List<String> workCellCodeList = (partCheckDetailList.stream().filter(o -> (null != o)).map(MesPartCheckDetail::getWorkCellCode).collect(Collectors.toList()))
                .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        workCellList = workCenterExtService.queryCellsByCenter(partCheckDetailList.get(0).getWorkCenterCode(), organizeCode);
        workCellList = CollectionUtils.isEmpty(workCellList) ? null :
                workCellList.stream().filter(o -> (null != o && workCellCodeList.contains(o.getWorkCellCode()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workCellList)) {
            return workCellList;
        }
        workCellList = workCellList.stream().filter(o -> null != o).distinct().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesWorkCell::getWorkCellCode))), ArrayList::new)
        );
        return workCellList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesWorkCell::getWorkCellCode)).collect(Collectors.toList());
    }

    @Override
    public ListPager<PartCheckDetailModel> queryPartCheckByCell(MesPartCheckDetail detail, Pager pager) {
        //1、修改单前选中的单据作业 的单据状态为点检中
        MesOrderJob orderJob = mesOrderJobRDao.getByProperty(new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ORDER_NO},
                new Object[]{detail.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtEnumUtil.IS_VAILD.VAILD.getValue(), detail.getOrderNo()});
        if (StringUtils.isEmpty(orderJob)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("该单据作业不存在")
                    .build();
        }
        //2、查询工位下所有的点检单
        pager = PagerHelper.getPager(pager, partCheckDao.queryPartCheckByPagerCount(detail));
        List<PartCheckDetailModel> checkDetailModelList = partCheckDao.queryPartCheckByPager(detail , pager);
        return new ListPager(checkDetailModelList, pager);
    }

    @Override
    public ListPager<MesPartCheckDetail> queryMesPartCheckDetail(MesPartCheckDetail mesPartCheckDetail, Pager pager) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(mesPartCheckDetail.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getWorkOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getProcessCode(), MesPcnExtConstWords.PROCESS_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getWorkCellCode(), MesPcnExtConstWords.WORK_CELL_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getShiftCode(), MesPcnExtConstWords.SHIFT_CODE, packBean);
        if (!StringUtils.isEmpty(mesPartCheckDetail.getCheckStartTime()) && !StringUtils.isEmpty(mesPartCheckDetail.getCheckEndTime())) {
            DdlPreparedPack.timeBuilder(mesPartCheckDetail.getCheckStartTime(), mesPartCheckDetail.getCheckEndTime(), MesPcnExtConstWords.CHECK_TIME, packBean, true);
        }
        DdlPreparedPack.getNumEqualPack(mesPartCheckDetail.getShiftGroupCheck(), MesPcnExtConstWords.SHIFT_GROUP_CHECK, packBean);
        DdlPreparedPack.getNumEqualPack(mesPartCheckDetail.getQualityCheck(), MesPcnExtConstWords.QUALITY_CHECK, packBean);
        DdlPreparedPack.getStringEqualPack(mesPartCheckDetail.getOrderNo(), MesPcnExtConstWords.ORDER_NO, packBean);
        pager = PagerHelper.getPager(pager, mesPartCheckDetailRDao.findByHqlWhereCount(packBean));
        packBean.setOrderByStr(mesPartCheckDetail.orderBy());
        return new ListPager(mesPartCheckDetailRDao.findByHqlWherePage(packBean, pager), pager);
    }
}
