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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.IMesWorkCellScanMonitorLogDao;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesScanMonitorContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.swslog.ISwsWriteDbLogService;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesWcEquipment;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
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.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Slf4j
@Service
public class MesWorkCellScanMonitorLogExtService implements ISwsWriteDbLogService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesEquipmentExtService equipmentExtService;

    @Autowired
    private IMesProdOrgExtService prodOrgExtService;

    @Autowired
    private IMesWorkCellScanMonitorLogDao workCellScanMonitorLogDao;

    private final static Map<String, List<String>> cellMsg2RepeatMap = new ConcurrentHashMap();

    @Override
    public void doWriteDbLog(StationResultBean resultBean) {

        //获取上下文工位扫描监控信息
        MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.getScanMonitorContext(resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getWorkCellCode());

        if (checkRepeat(resultBean, scanMonitorContext)) return;

        if (null == scanMonitorContext) scanMonitorContext = new MesScanMonitorContext();

        restoreBasicInfo(resultBean, scanMonitorContext);

        if (null == scanMonitorContext)
            log.info("工厂{}生产线{}工位{}: MesWorkCellScanMonitorLogExtService --- 上下文当前不存在工位扫描监控信息 --- {}", resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getWorkCellCode(), resultBean.toWriteDbString());

        workCellScanMonitorLogDao.insertWorkCellScanMonitorLog(resultBean, scanMonitorContext);

    }

    @Override
    public void doRestoreDbLog(StationResultBean resultBean) {

        if (StringUtils.isEmpty(resultBean.getScanInfo()) || CollectionUtils.isEmpty(resultBean.getResultList())) return;

        List<MesProductionPsOutContext> productionPsOutContextList = resultBean.getResultList();

        workCellScanMonitorLogDao.updateWorkCellScanMonitorLog(resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getUserInfo(), Long.valueOf(resultBean.getScanInfo()), productionPsOutContextList);

    }

    private Boolean checkRepeat(StationResultBean resultBean, MesScanMonitorContext scanMonitorContext) {

        initCellMsg2RepeatMap(resultBean);

        Long mouldRecordId = (null != scanMonitorContext && !StringUtils.isEmpty(scanMonitorContext.getMouldRecordId())) ? scanMonitorContext.getMouldRecordId() : null;
        String mouldRecordIdStr = !StringUtils.isEmpty(mouldRecordId) ? mouldRecordId.toString() : MesPcnExtConstWords.EMPTY;

        if (!cellMsg2RepeatMap.get(resultBean.getClientInfo()).get(0).equals(mouldRecordIdStr)) {
            cellMsg2RepeatMap.get(resultBean.getClientInfo()).clear();
            cellMsg2RepeatMap.get(resultBean.getClientInfo()).add(0, mouldRecordIdStr);

            //补偿数据: 将工位排除当前开模ID的未处理的的数据改成已处理,未同步
            Integer count = workCellScanMonitorLogDao.updateWorkCellScanMonitorLog(resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getWorkCellCode(), mouldRecordId);

            log.info("工厂{}生产线{}工位{}: MesWorkCellScanMonitorLogExtService --- 补偿同步条数:{} ---", resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getWorkCellCode(), count);

        }

        if (resultBean.getIsCheckRepeat().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0) return false;

        synchronized ((resultBean.getClientInfo() + this.getClass().getSimpleName()).intern()) {

            if (cellMsg2RepeatMap.get(resultBean.getClientInfo()).contains(removeDatetime(resultBean.getMessage()))) return true;

            cellMsg2RepeatMap.get(resultBean.getClientInfo()).add(removeDatetime(resultBean.getMessage()));

            return false;

        }

    }

    private void initCellMsg2RepeatMap(StationResultBean resultBean) {

        cellMsg2RepeatMap.computeIfAbsent(resultBean.getClientInfo(), o -> {

            List<String> list = new CopyOnWriteArrayList<>();

            list.add(0, MesPcnExtConstWords.EMPTY);

            return list;

        });

    }

    private String removeDatetime(String message) {
        if (StringUtils.isEmpty(message)) return message;
        message = message.replaceAll("[0-9]{4}[-][0-9]{2}[-][0-9]{2}", MesPcnExtConstWords.DATE_FORMAT_SEPARATOR);
        message = message.replaceAll("[0-9]{2}[:][0-9]{2}[:][0-9]{2}", MesPcnExtConstWords.TIME_FORMAT);
        message = message.replaceAll("[HH:mm:ss.][0-9]{3}", MesPcnExtConstWords.SSS);
        return message;
    }

    private void restoreBasicInfo(StationResultBean resultBean, MesScanMonitorContext scanMonitorContext) {
        MesWcEquipment wcEquipment = null;
        if (StringUtils.isEmpty(scanMonitorContext.getEquipmentCode())) {
            wcEquipment = equipmentExtService.getWcEquipment(resultBean.getOrganizeCode(), resultBean.getWorkCenterCode(), resultBean.getWorkCellCode());
            scanMonitorContext.setEquipmentCode(null != wcEquipment ? wcEquipment.getEquipmentCode() : null);
            scanMonitorContext.setEquipmentName(null != wcEquipment ? wcEquipment.getEquipmentName() : null);
        }

        if (StringUtils.isEmpty(resultBean.getAreaCode())) {
            if (!StringUtils.isEmpty(scanMonitorContext.getAreaCode())) resultBean.areaCode(scanMonitorContext.getAreaCode());
            else if (null != wcEquipment && !StringUtils.isEmpty(wcEquipment.getAreaCode())) resultBean.areaCode(wcEquipment.getAreaCode());
            else {
                MesWorkCenter workCenter = prodOrgExtService.getWorkCenterDb(resultBean.getOrganizeCode(), resultBean.getWorkCenterCode());
                if (null != workCenter) resultBean.areaCode(workCenter.getAreaCode());
            }
        }
    }

}
