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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
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.repository.*;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

@Slf4j
@Service
public class MesProdOrgExtService implements IMesProdOrgExtService {

    @Autowired
    private MesWorkCenterRepository workCenterRepository;

    @Autowired
    private MesWorkCellRepository workCellRepository;

    @Autowired
    private MesCraftRepository craftRepository;

    @Autowired
    private MesWorkCellExtendCfgRepository workCellExtendCfgRepository;

    @Autowired
    private MesWorkCellPartPrinterCfgRepository workCellPartPrinterCfgRepository;

    @Override
    public MesWorkCenter getWorkCenterDb(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        return workCenterRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
    }

    @Override
    public String getErpWorkCenterCode(String organizeCode, String workCenterCode) {
        MesWorkCenter workCenterDb = getWorkCenterDb(organizeCode, workCenterCode);
        return null != workCenterDb ? workCenterDb.getErpWorkCenter() : null;
    }

    @Override
    public MesWorkCell getWorkCellDb(String organizeCode, String workCenterCode, String workCellCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return null;
        return workCellRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode});
    }

    @Override
    public MesWorkCell getWorkCellDb(String organizeCode, String workCenterCode, String workCellCode, Boolean isCheckEndWorkCell) {
        if (!isCheckEndWorkCell) return getWorkCellDb(organizeCode, workCenterCode, workCellCode);
        List<MesWorkCell> workCellList = getWorkCellList(organizeCode, workCenterCode);
        Optional<MesWorkCell> optional = CollectionUtils.isEmpty(workCellList) ? null : workCellList.stream().filter(o -> (null != o && o.getWorkCellCode().equals(workCellCode))).findFirst();
        if (null == optional || !optional.isPresent()) return null;
        if (workCellList.size() == 1) optional.get().setIsEndWorkCell(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
        return optional.get();
    }

    @Override
    public List<MesWorkCell> getWorkCellList(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        List<MesWorkCell> workCellList = workCellRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
        if (!CollectionUtils.isEmpty(workCellList))
            workCellList = workCellList.stream().filter(o -> null != o).distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesWorkCell::getWorkCellCode))), ArrayList::new));
        return workCellList;
    }

    @Override
    public List<MesWorkCenter> getWorkCenterList(String organizeCode, List<String> workCenterCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(workCenterCodeList)) return null;
        if (workCenterCodeList.size() != 1) workCenterCodeList = workCenterCodeList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (workCenterCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(workCenterCodeList.get(0), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        else DdlPreparedPack.getInPackList(workCenterCodeList, MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        return workCenterRepository.findByHqlWhere(packBean);
    }

    @Override
    public Map<String, String> getWorkCenterCodeMap(String organizeCode, List<String> workCenterCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(workCenterCodeList)) return null;
        List<MesWorkCenter> workCenterList = getWorkCenterList(organizeCode, workCenterCodeList);
        if (CollectionUtils.isEmpty(workCenterList)) return null;
        workCenterList = workCenterList.stream().filter(o -> null != o).distinct().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesWorkCenter::getWorkCenterCode))), ArrayList::new)
        );
        return workCenterList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCenter::getWorkCenterCode, MesWorkCenter::getWorkCenterName));
    }

    @Override
    public List<MesWorkCell> getWorkCellList(String organizeCode, List<String> workCellCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(workCellCodeList)) return null;
        if (workCellCodeList.size() != 1) workCellCodeList = workCellCodeList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (workCellCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(workCellCodeList.get(0), MesPcnExtConstWords.WORK_CELL_CODE, packBean);
        else DdlPreparedPack.getInPackList(workCellCodeList, MesPcnExtConstWords.WORK_CELL_CODE, packBean);
        return workCellRepository.findByHqlWhere(packBean);
    }

    @Override
    public Map<String, String> getWorkCellCodeMap(String organizeCode, List<String> workCellCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(workCellCodeList)) return null;
        List<MesWorkCell> workCellList = getWorkCellList(organizeCode, workCellCodeList);
        if (CollectionUtils.isEmpty(workCellList)) return null;
        workCellList = workCellList.stream().filter(o -> null != o).distinct().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(
                        o -> new StringJoiner(MesPcnExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString()))), ArrayList::new)
        );
        return workCellList.stream().filter(o -> null != o).collect(Collectors.toMap(
                o -> new StringJoiner(MesPcnExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString(), MesWorkCell::getWorkCellName));
    }

    @Override
    public List<MesCraft> getCraftList(String organizeCode, List<String> craftCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(craftCodeList)) return null;
        if (craftCodeList.size() != 1) craftCodeList = craftCodeList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (craftCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(craftCodeList.get(0), MesPcnExtConstWords.CRAFT_CODE, packBean);
        else DdlPreparedPack.getInPackList(craftCodeList, MesPcnExtConstWords.CRAFT_CODE, packBean);
        return craftRepository.findByHqlWhere(packBean);
    }

    @Override
    public Map<String, String> getCraftCodeMap(String organizeCode, List<String> craftCodeList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(craftCodeList)) return null;
        List<MesCraft> craftList = getCraftList(organizeCode, craftCodeList);
        if (CollectionUtils.isEmpty(craftList)) return null;
        craftList = craftList.stream().filter(o -> null != o).distinct().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesCraft::getCraftCode))), ArrayList::new)
        );
        return craftList.stream().filter(o -> null != o).collect(Collectors.toMap(MesCraft::getCraftCode, MesCraft::getCraftName));
    }

    @Override
    public MesWorkCellExtendCfg getWorkCellExtendCfg(String organizeCode, String workCenterCodeBak, String workCellCodeBak, Integer extendType) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCodeBak) || StringUtils.isEmpty(workCellCodeBak) || StringUtils.isEmpty(extendType)) return null;
        return workCellExtendCfgRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE_BAK, MesPcnExtConstWords.WORK_CELL_CODE_BAK, MesPcnExtConstWords.EXTEND_TYPE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCodeBak, workCellCodeBak, extendType});
    }


    @Override
    public List<MesWorkCellExtendCfg> getWorkCellExtendCfgList(String organizeCode, String workCenterCode, String workCellCode, Integer extendType) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode) || StringUtils.isEmpty(extendType)) return null;
        return workCellExtendCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE, MesPcnExtConstWords.EXTEND_TYPE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode, extendType});
    }

    @Override
    public List<MesWorkCellExtendCfg> getWorkCellExtendCfgRvListSortByBak(String organizeCode, String workCenterCodeBak, String workCellCodeBak) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCodeBak) || StringUtils.isEmpty(workCellCodeBak)) return null;
        MesWorkCellExtendCfg workCellExtendCfg = getWorkCellExtendCfg(organizeCode, workCenterCodeBak, workCellCodeBak, MesExtEnumUtil.WORK_CELL_EXTEND_TYPE.RV.getValue());
        if (null == workCellExtendCfg) return null;
        List<MesWorkCellExtendCfg> workCellExtendCfgList = getWorkCellExtendCfgList(organizeCode, workCellExtendCfg.getWorkCenterCode(), workCellExtendCfg.getWorkCellCode(), MesExtEnumUtil.WORK_CELL_EXTEND_TYPE.RV.getValue());
        List<MesWorkCellExtendCfg> workCellExtendCfgListAfter = workCellExtendCfgList.stream().filter(o -> (null != o && workCellExtendCfg.getSeq().compareTo(o.getSeq()) <= 0)).sorted(Comparator.comparing(MesWorkCellExtendCfg::getSeq)).collect(Collectors.toList());
        List<MesWorkCellExtendCfg> workCellExtendCfgListBefore = workCellExtendCfgList.stream().filter(o -> (null != o && workCellExtendCfg.getSeq().compareTo(o.getSeq()) > 0)).sorted(Comparator.comparing(MesWorkCellExtendCfg::getSeq)).collect(Collectors.toList());
        workCellExtendCfgList = new ArrayList<>();
        workCellExtendCfgList.addAll(workCellExtendCfgListAfter);
        workCellExtendCfgList.addAll(workCellExtendCfgListBefore);
        return workCellExtendCfgList;
    }

    @Override
    public List<MesWorkCellExtendCfg> getWorkCellExtendCfgRvListByBak(String organizeCode, String workCenterCodeBak, String workCellCodeBak) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCodeBak) || StringUtils.isEmpty(workCellCodeBak)) return null;
        MesWorkCellExtendCfg workCellExtendCfg = getWorkCellExtendCfg(organizeCode, workCenterCodeBak, workCellCodeBak, MesExtEnumUtil.WORK_CELL_EXTEND_TYPE.RV.getValue());
        if (null == workCellExtendCfg) return null;
        return getWorkCellExtendCfgList(organizeCode, workCellExtendCfg.getWorkCenterCode(), workCellExtendCfg.getWorkCellCode(), MesExtEnumUtil.WORK_CELL_EXTEND_TYPE.RV.getValue());
    }

    @Override
    public List<MesWorkCellPartPrinterCfg> getWorkCellPartPrinterCfgList(String organizeCode, String workCenterCode, String workCellCode) {
        return workCellPartPrinterCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode});
    }

}
