package cn.estsh.i3plus.ext.mes.pcn.apiservice.daoimpl;


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.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;

@Service
public class MesWorkCellScanMonitorLogDao implements IMesWorkCellScanMonitorLogDao {

    @Value("${mes.sharding.append.org:}")
    public String mesShardingAppendOrg;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private SnowflakeIdMaker snowflakeIdMaker;

    @Override
    public void insertWorkCellScanMonitorLog(StationResultBean resultBean, MesScanMonitorContext scanMonitorContext) {

        if (null == resultBean || null == scanMonitorContext) return;

        StringBuffer builder = new StringBuffer();

        builder.append(" insert into mes_work_cell_scan_monitor_log_");
        if (!StringUtils.isEmpty(mesShardingAppendOrg) && mesShardingAppendOrg.toUpperCase().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.name())) builder.append(resultBean.getOrganizeCode().toLowerCase()).append(MesPcnExtConstWords.E_UNDERLINE);
        builder.append(resultBean.getWorkCenterCode().toLowerCase());
        builder.append("( id, organize_code, is_valid, is_deleted, create_user, create_date_time, modify_user, modify_date_time,");
        builder.append(" description, remark, system_sync_date_time, system_sync_status,");
        builder.append(" area_code, work_center_code, work_cell_code, equipment_code, equipment_name, process_code, process_name, craft_code, craft_name,");
        builder.append(" mould_record_id, scan_info, work_order_no, serial_number, product_sn, cust_sn, part_no, part_name,");
        builder.append(" step_code, log_type, message, message_type, deal_status, org_work_code)");
        builder.append(" values ( :id , :organizeCode , :isValid , :isDeleted , :createUser , :createDatetime , :modifyUser , :modifyDatetime ,");
        builder.append(" :description , :remark , :systemSyncDatetime , :systemSyncStatus ,");
        builder.append(" :areaCode , :workCenterCode , :workCellCode , :equipmentCode , :equipmentName , :processCode , :processName , :craftCode , :craftName ,");
        builder.append(" :mouldRecordId , :scanInfo , :workOrderNo , :serialNumber , :productSn , :custSn , :partNo , :partName ,");
        builder.append(" :stepCode , :logType , :message , :messageType , :dealStatus , :orgWorkCode )");

        Query insert = entityManager.createNativeQuery(builder.toString());

        insert.setParameter(MesPcnExtConstWords.ID, snowflakeIdMaker.nextId());
        insert.setParameter(MesPcnExtConstWords.ORGANIZE_CODE, resultBean.getOrganizeCode());
        insert.setParameter(MesPcnExtConstWords.IS_VALID, CommonEnumUtil.IS_VAILD.VAILD.getValue());
        insert.setParameter(MesPcnExtConstWords.IS_DELETED, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
        insert.setParameter(MesPcnExtConstWords.CREATE_USER, resultBean.getUserInfo());
        insert.setParameter(MesPcnExtConstWords.CREATE_DATE_TIME, TimeTool.getNowTime(true));
        insert.setParameter(MesPcnExtConstWords.MODIFY_USER, resultBean.getUserInfo());
        insert.setParameter(MesPcnExtConstWords.MODIFY_DATE_TIME, TimeTool.getNowTime(true));
        insert.setParameter(MesPcnExtConstWords.DESCRIPTION, null);
        insert.setParameter(MesPcnExtConstWords.REMARK, null);
        insert.setParameter(MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME, null);
        insert.setParameter(MesPcnExtConstWords.AREA_CODE, resultBean.getAreaCode());
        insert.setParameter(MesPcnExtConstWords.WORK_CENTER_CODE, resultBean.getWorkCenterCode());
        insert.setParameter(MesPcnExtConstWords.WORK_CELL_CODE, resultBean.getWorkCellCode());
        insert.setParameter(MesPcnExtConstWords.EQUIPMENT_CODE, scanMonitorContext.getEquipmentCode());
        insert.setParameter(MesPcnExtConstWords.EQUIPMENT_NAME, scanMonitorContext.getEquipmentName());
        insert.setParameter(MesPcnExtConstWords.PROCESS_CODE, scanMonitorContext.getProcessCode());
        insert.setParameter(MesPcnExtConstWords.PROCESS_NAME, scanMonitorContext.getProcessName());
        insert.setParameter(MesPcnExtConstWords.CRAFT_CODE, scanMonitorContext.getCraftCode());
        insert.setParameter(MesPcnExtConstWords.CRAFT_NAME, scanMonitorContext.getCraftName());
        insert.setParameter(MesPcnExtConstWords.MOULD_RECORD_ID, scanMonitorContext.getMouldRecordId());
        insert.setParameter(MesPcnExtConstWords.SCAN_INFO, resultBean.getScanInfo());
        insert.setParameter(MesPcnExtConstWords.WORK_ORDER_NO, null);
        insert.setParameter(MesPcnExtConstWords.SERIAL_NUMBER, null);
        insert.setParameter(MesPcnExtConstWords.PRODUCT_SN, null);
        insert.setParameter(MesPcnExtConstWords.CUST_SN, null);
        insert.setParameter(MesPcnExtConstWords.PART_NO, null);
        insert.setParameter(MesPcnExtConstWords.PART_NAME, null);
        insert.setParameter(MesPcnExtConstWords.STEP_CODE, resultBean.getStepCode());
        insert.setParameter(MesPcnExtConstWords.LOG_TYPE, resultBean.getLogType());
        insert.setParameter(MesPcnExtConstWords.MESSAGE, resultBean.getMessage());
        insert.setParameter(MesPcnExtConstWords.MESSAGE_TYPE, MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_MESSAGE_TYPE.codeOfValue(resultBean.getDataType()));
        insert.setParameter(MesPcnExtConstWords.ORG_WORK_CODE, new StringJoiner(MesPcnExtConstWords.E_UNDERLINE).add(resultBean.getOrganizeCode()).add(resultBean.getWorkCenterCode()).toString());
        //存在开模ID的记录延迟同步
        if (!StringUtils.isEmpty(scanMonitorContext.getMouldRecordId())) {
            insert.setParameter(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            insert.setParameter(MesPcnExtConstWords.DEAL_STATUS, MesExtEnumUtil.MES_LOG_DEAL_STATUS.UNDEAL.getValue());
        } else {
            insert.setParameter(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
            insert.setParameter(MesPcnExtConstWords.DEAL_STATUS, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue());
        }

        insert.executeUpdate();
    }

    @Override
    public Integer updateWorkCellScanMonitorLog(String organizeCode, String workCenterCode, String workCellCode, Long mouldRecordId) {

        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return MesPcnExtConstWords.ZERO;

        StringBuffer builder = new StringBuffer();

        builder.append(" update mes_work_cell_scan_monitor_log_");
        if (!StringUtils.isEmpty(mesShardingAppendOrg) && mesShardingAppendOrg.toUpperCase().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.name())) builder.append(organizeCode.toLowerCase()).append(MesPcnExtConstWords.E_UNDERLINE);
        builder.append(workCenterCode.toLowerCase());
        builder.append(" set system_sync_status = :systemSyncStatus , deal_status = :dealStatus1 ");
        builder.append(" where organize_code = :organizeCode and deal_status = :dealStatus2 and work_cell_code = :workCellCode ");
        if (!StringUtils.isEmpty(mouldRecordId)) builder.append(" and mould_record_id != :mouldRecordId ");

        Query update = entityManager.createNativeQuery(builder.toString());

        update.setParameter(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
        update.setParameter("dealStatus1", MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue());

        update.setParameter(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode);
        update.setParameter("dealStatus2", MesExtEnumUtil.MES_LOG_DEAL_STATUS.UNDEAL.getValue());
        update.setParameter(MesPcnExtConstWords.WORK_CELL_CODE, workCellCode);
        if (!StringUtils.isEmpty(mouldRecordId)) update.setParameter(MesPcnExtConstWords.MOULD_RECORD_ID, mouldRecordId);

        return update.executeUpdate();
    }

    @Override
    public Integer updateWorkCellScanMonitorLog(String organizeCode, String workCenterCode, String userInfo, Long mouldRecordId, List<MesProductionPsOutContext> productionPsOutContextList) {

        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(mouldRecordId) || CollectionUtils.isEmpty(productionPsOutContextList)) return MesPcnExtConstWords.ZERO;

        String workOrderNo = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkOrderNo()))).map(MesProductionPsOutContext::getWorkOrderNo).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        String serialNumber = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getSerialNumber()))).map(MesProductionPsOutContext::getSerialNumber).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        String productSn = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProductSn()))).map(MesProductionPsOutContext::getProductSn).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        String custSn = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCustSn()))).map(MesProductionPsOutContext::getCustSn).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        String partNo = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartNo()))).map(MesProductionPsOutContext::getPartNo).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        String partName = productionPsOutContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPartName()))).map(MesProductionPsOutContext::getPartName).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));

        StringBuffer builder = new StringBuffer();

        builder.append(" update mes_work_cell_scan_monitor_log_");
        if (!StringUtils.isEmpty(mesShardingAppendOrg) && mesShardingAppendOrg.toUpperCase().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.name())) builder.append(organizeCode.toLowerCase()).append(MesPcnExtConstWords.E_UNDERLINE);
        builder.append(workCenterCode.toLowerCase());
        builder.append(" set work_order_no = :workOrderNo , serial_number = :serialNumber , product_sn = :productSn , cust_sn = :custSn , part_no = :partNo , part_name = :partName ,");
        builder.append(" modify_user = :modifyUser , modify_date_time = :modifyDatetime , system_sync_status = :systemSyncStatus , deal_status = :dealStatus ");
        builder.append(" where organize_code = :organizeCode and mould_record_id = :mouldRecordId ");

        Query update = entityManager.createNativeQuery(builder.toString());

        update.setParameter(MesPcnExtConstWords.WORK_ORDER_NO, workOrderNo);
        update.setParameter(MesPcnExtConstWords.SERIAL_NUMBER, serialNumber);
        update.setParameter(MesPcnExtConstWords.PRODUCT_SN, productSn);
        update.setParameter(MesPcnExtConstWords.CUST_SN, custSn);
        update.setParameter(MesPcnExtConstWords.PART_NO, partNo);
        update.setParameter(MesPcnExtConstWords.PART_NAME, partName);
        update.setParameter(MesPcnExtConstWords.MODIFY_USER, userInfo);
        update.setParameter(MesPcnExtConstWords.MODIFY_DATE_TIME, TimeTool.getNowTime(true));
        update.setParameter(MesPcnExtConstWords.SYSTEM_SYNC_STATUS, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
        update.setParameter(MesPcnExtConstWords.DEAL_STATUS, MesExtEnumUtil.MES_LOG_DEAL_STATUS.DEAL_SUCCESS.getValue());

        update.setParameter(MesPcnExtConstWords.ORGANIZE_CODE, organizeCode);
        update.setParameter(MesPcnExtConstWords.MOULD_RECORD_ID, mouldRecordId);

        return update.executeUpdate();

    }

}
