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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyPlcCollectDataJobService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.SxWorkCellTaktCollectPlcCfg;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.SxWorkCellTaktCollectPlcCfgRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
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;

/**
 * 第三方PLC数据采集定时任务-采集工位节拍实现
 */
@Slf4j
@Service(value = "SxThirdPartyPlcCollectCellTaktService")
public class SxThirdPartyPlcCollectCellTaktService implements ISxThirdPartyPlcCollectDataJobService {

    @Autowired
    private SxWorkCellTaktCollectPlcCfgRepository workCellTaktCollectPlcCfgRepository;

    @Override
    public void doThirdPartyPlcCollectData(Map<String, Object> paramMap) {

        String organizeCode = (String) paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE);

        log.info("工厂{}第三方PLC数据采集 --- STRATEGY {} EXEC SERVICE START --- PARAM:{}", organizeCode, MesPcnExtConstWords.CELL_TAKT, paramMap.toString());

        if (checkOrgIsStopMonitor(organizeCode, (String) paramMap.get(MesPcnExtConstWords.STATUS))) return;

        String limitCfg = paramMap.containsKey(MesPcnExtConstWords.LIMIT) ? (String) paramMap.get(MesPcnExtConstWords.LIMIT) : MesPcnExtConstWords.EMPTY;

        Map<String, Object> cfgMap = getWorkCellTaktCollectPlcCfgList(organizeCode, limitCfg);

        log.info("工厂{}第三方PLC数据采集 --- STRATEGY {} EXEC SERVICE --- CFGMAP:{}", organizeCode, MesPcnExtConstWords.CELL_TAKT, cfgMap.toString());

        if (!SxThirdPartyPlcCollectDispatchSingleton.getIsInit()) SxThirdPartyPlcCollectDispatchSingleton.getInstance();

        SxThirdPartyPlcCollectDispatchSingleton.execMonitor(organizeCode, MesPcnExtConstWords.CELL_TAKT, cfgMap, true);

        log.info("工厂{}第三方PLC数据采集 --- STRATEGY {} EXEC SERVICE END ---", organizeCode, MesPcnExtConstWords.CELL_TAKT);

    }

    private Boolean checkOrgIsStopMonitor(String organizeCode, String status) {
        if (!StringUtils.isEmpty(status) && status.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) return false;
        if (SxThirdPartyPlcCollectDispatchSingleton.getIsInit()) SxThirdPartyPlcCollectDispatchSingleton.execMonitor(organizeCode, MesPcnExtConstWords.CELL_TAKT, null, true);
        log.info("工厂{}第三方PLC数据采集 --- STRATEGY {} EXEC SERVICE END --- MONITOR CLOSED COMPLETED ---", organizeCode, MesPcnExtConstWords.CELL_TAKT);
        return true;
    }

    private Map<String, Object> getWorkCellTaktCollectPlcCfgList(String organizeCode, String limitCfg) {
        String value = "{\"PLC_CODE\":\"%s\", \"LIMIT\":\"%s\"}";
        List<SxWorkCellTaktCollectPlcCfg> workCellTaktCollectPlcCfgList = workCellTaktCollectPlcCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.STATUS},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()});
        workCellTaktCollectPlcCfgList = CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? null :
                workCellTaktCollectPlcCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPlcCode()))).distinct().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> new StringJoiner(MesPcnExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString()))), ArrayList::new));
        workCellTaktCollectPlcCfgList = CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? null :
                workCellTaktCollectPlcCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPlcCode()))).distinct().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SxWorkCellTaktCollectPlcCfg::getPlcCode))), ArrayList::new));
        return CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? new HashMap<>() :
                workCellTaktCollectPlcCfgList.stream().filter(o -> null != o).collect(Collectors.toMap(o ->
                        new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.CELL_TAKT).add(organizeCode).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString(), o -> String.format(value, o.getPlcCode(), limitCfg)));
    }

}
