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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
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.*;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 容器条码上料业务
 */
@Service
public class MesStationContainerSnExtService implements IMesStationContainerSnExtService {

    @Autowired
    private MesStationRepository stationRepository;

    @Autowired
    private MesContainerSnStationRepository containerSnStationRepository;

    @Autowired
    private MesContainerPackageRepository containerPackageRepository;

    @Autowired
    private MesContainerPackageDetailRepository containerPackageDetailRepository;

    @Autowired
    private MesContainerPackageDetailFeedingRepository containerPackageDetailFeedingRepository;

    //根据设备代码查询站点信息
    @Override
    public List<MesStation> getStationList(String organizeCode, String equipmentCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(equipmentCode)) return null;
        return stationRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.EQUIPMENT_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), equipmentCode});
    }

    //获取站点关联的容器条码
    @Override
    public Map<String, List<MesContainerSnStation>> getContainerSnStationMap(String organizeCode, List<MesStation> stationList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
        List<MesContainerSnStation> containerSnStationList = getContainerSnStationList(organizeCode, stationList);
        return CollectionUtils.isEmpty(containerSnStationList) ? null :
                containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn));
    }

    //获取站点关联的容器条码
    @Override
    public List<MesContainerSnStation> getContainerSnStationList(String organizeCode, List<MesStation> stationList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
        List<String> stations = stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStation()))).map(MesStation::getStation).collect(Collectors.toList());
        return getContainerSnStationListByStation(organizeCode, stations);
    }

    //获取站点关联的容器条码
    @Override
    public List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (stationList.size() == 1) DdlPreparedPack.getStringEqualPack(stationList.get(0), MesPcnExtConstWords.STATION, packBean);
        else DdlPreparedPack.getInPackList(stationList, MesPcnExtConstWords.STATION, packBean);
        return containerSnStationRepository.findByHqlWhere(packBean);
    }

    //获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<MesContainerPackageDetailContext> getContainerPackageDetailContext(String organizeCode, List<MesStation> stationList) {
        //获取站点关联的容器条码, key = containerSn
        Map<String, List<MesContainerSnStation>> containerSnStationMap = getContainerSnStationMap(organizeCode, stationList);
        if (CollectionUtils.isEmpty(containerSnStationMap)) return null;
        //获取容器条码上料主表信息【已关箱】
        List<MesContainerPackage> containerPackageList = getContainerPackageListByContainerSn(organizeCode,
                new ArrayList<>(containerSnStationMap.keySet()), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
        if (CollectionUtils.isEmpty(containerPackageList)) return null;
        //获取容器条码上料明细表信息
        List<MesContainerPackageDetail> containerPackageDetailList = getContainerPackageDetailList(organizeCode, containerPackageList);
        if (CollectionUtils.isEmpty(containerPackageDetailList)) return null;
        //站点根据名称分组
        Map<String, List<MesStation>> stationMap = stationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getStation));
        //封装容器条码对应的【可扣减】的上料明细表信息
        List<MesContainerPackageDetailContext> containerSnStationContextList = new ArrayList<>();
        for (MesContainerPackageDetail containerPackageDetail : containerPackageDetailList) {
            if (null == containerPackageDetail) continue;
            MesContainerSnStation containerSnStation = containerSnStationMap.get(containerPackageDetail.getContainerSn()).get(0);
            containerSnStationContextList.add(new MesContainerPackageDetailContext(containerPackageDetail).containerSnStation(containerSnStation).station(stationMap.get(containerSnStation.getStation()).get(0)));
        }
        //根据 主表seq,主表createDatetime,明细表createDatetime 正序
        containerSnStationContextList = containerSnStationContextList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesContainerPackageDetailContext::getSeq)
                .thenComparing(MesContainerPackageDetailContext::getCreateDatetime2Package).thenComparing(MesContainerPackageDetailContext::getCreateDatetime)).collect(Collectors.toList());
        return containerSnStationContextList;
    }

    //获取容器条码上料主表信息
    @Override
    public List<MesContainerPackage> getContainerPackageList(String organizeCode, List<MesContainerSnStation> containerSnStationList, Integer packageStatus) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnStationList)) return null;
        List<String> containerSnList = containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()))).map(MesContainerSnStation::getContainerSn).collect(Collectors.toList());
        return getContainerPackageListByContainerSn(organizeCode, containerSnList, packageStatus);
    }

    //获取容器条码上料主表信息
    @Override
    public List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (containerSnList.size() == 1) DdlPreparedPack.getStringEqualPack(containerSnList.get(0), MesPcnExtConstWords.CONTAINER_SN, packBean);
        else DdlPreparedPack.getInPackList(containerSnList, MesPcnExtConstWords.CONTAINER_SN, packBean);
        DdlPreparedPack.getNumEqualPack(packageStatus, MesPcnExtConstWords.PACKAGE_STATUS, packBean);
        return containerPackageRepository.findByHqlWhere(packBean);
    }

    //获取容器条码上料明细表信息【可扣减】
    @Override
    public List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerPackageList)) return null;
        List<Long> idList = containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getId).collect(Collectors.toList());
        return getContainerPackageDetailListById(organizeCode, idList);
    }

    //获取容器条码上料明细表信息【可扣减】
    @Override
    public List<MesContainerPackageDetail> getContainerPackageDetailListById(String organizeCode, List<Long> idList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(idList)) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (idList.size() == 1) DdlPreparedPack.getNumEqualPack(idList.get(0), MesPcnExtConstWords.PID, packBean);
        else DdlPreparedPack.getInPackList(idList, MesPcnExtConstWords.PID, packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.CONTAINER_BARCODE_STATUS.STATUS_10.getValue(), MesPcnExtConstWords.SN_STATUS, packBean);
        return containerPackageDetailRepository.findByHqlWhere(packBean);
    }

    //获取容器条码的一条上料明细表信息【可扣减】
    @Override
    public Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(id)) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(id, MesPcnExtConstWords.PID, packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.CONTAINER_BARCODE_STATUS.STATUS_10.getValue(), MesPcnExtConstWords.SN_STATUS, packBean);
        return containerPackageDetailRepository.isExitByHql(packBean);
    }

    //写入扣料记录
    @Override
    public void insertContainerPackageDetailFeeding(StationRequestBean reqBean, MesContainerPackageDetailContext containerPackageDetailContext, MesProductionPsOutContext productionPsOutContext) {
        MesContainerPackageDetailFeeding containerPackageDetailFeeding = new MesContainerPackageDetailFeeding();
        BeanUtils.copyProperties(containerPackageDetailContext, containerPackageDetailFeeding, MesPcnExtConstWords.BASE_BEAN_FIELDS);
        containerPackageDetailFeeding.setQty(containerPackageDetailContext.getDeductionQty());
        containerPackageDetailFeeding.setSourceId(containerPackageDetailContext.getId());
        if (null != productionPsOutContext) {
            containerPackageDetailFeeding.setProductSn(productionPsOutContext.getProductSn());
            containerPackageDetailFeeding.setProductSnId(productionPsOutContext.getId());
        }
        ConvertBean.serviceModelInitialize(containerPackageDetailFeeding, reqBean.getUserInfo());
        containerPackageDetailFeedingRepository.insert(containerPackageDetailFeeding);
    }

    @Override
    public void updateContainerPackageDetail(String organizeCode, String userInfo, Long id, Integer snStatus) {
        containerPackageDetailRepository.updateByProperties(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
                new Object[]{organizeCode, id},
                new String[]{MesPcnExtConstWords.SN_STATUS, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                new Object[]{snStatus, userInfo, TimeTool.getNowTime(true), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});
    }

}
