package com.eactive.eai.rms.onl.transaction.extnl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.adapter.Keys;
import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.data.entity.onl.message.EAIMessageEntity;
import com.eactive.eai.data.entity.onl.message.QEAIMessageEntity;
import com.eactive.eai.data.entity.onl.message.QServiceMessageEntity;
import com.eactive.eai.data.entity.onl.message.ServiceMessageEntity;
import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageInfo;
import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageItem;
import com.eactive.eai.rms.common.base.OnlBaseService;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.util.StringUtils;
import com.eactive.eai.rms.data.entity.onl.eaimsg.EAIMessageService;
import com.eactive.eai.rms.data.entity.onl.eaimsg.EAIMessageUISearch;
import com.eactive.eai.rms.data.entity.onl.sequence.SequenceEntity;
import com.eactive.eai.rms.data.entity.onl.sequence.SequenceService;
import com.eactive.eai.rms.data.entity.onl.stdmessage.StandardMessageInfoService;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.eactive.eai.rms.onl.manage.adapter.adapter.AdapterDao;
import com.eactive.eai.rms.onl.manage.adapter.adapter.AdapterManService;
import com.eactive.eai.rms.onl.manage.adapter.adapter.ui.AdapterGroupUI;
import com.eactive.eai.rms.onl.manage.rule.transform.TransformMappingManService;
import com.eactive.eai.rms.onl.manage.serviceinfo.bizkey.FieldExtractInfoService;
import com.eactive.eai.rms.onl.manage.serviceinfo.bizkey.FieldExtractInfoUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.EaiMsgManService;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.mapping.ServiceMessageUIMapper;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.ui.CondPerRtgInfoUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.ui.EAIReferenceMessageUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.ui.ServiceMessageUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageItemUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageManService;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageUI;
import com.eactive.eai.rms.onl.manage.serviceinfo.stdmessage.StdMessageUIMapper;
import com.eactive.eai.rms.onl.transaction.apim.StandardMessageInfoQueryServiceForApi;
import com.eactive.eai.rms.onl.transaction.extnl.mapping.InterfaceManUIMapper;
import com.eactive.eai.rms.onl.transaction.extnl.ui.InterfaceUI;
import com.querydsl.core.Tuple;

@Service
@Transactional
public class InterfaceManService extends OnlBaseService {

	@Autowired
	@Qualifier("interfaceDao")
	private InterfaceDao dao;

	@Autowired
	@Qualifier("adapterDao")
	private AdapterDao adapterDao;

	@Autowired
	@Qualifier("monitoringContext")
	private MonitoringContext monitoringContext;

	@Autowired
	@Qualifier("transformMappingManService")
	private TransformMappingManService transMapping;

	@Autowired
	@Qualifier("fieldExtractInfoService")
	private FieldExtractInfoService fieldExtractInfoService;

	@Autowired
	private InterfaceManUIMapper interfaceManUIMapper;

	@Autowired
	private AdapterManService adapterManService;

	@Autowired
	private EAIMessageService eaiMessageService;

	@Autowired
	@Qualifier("standardMessageInfoQueryServiceForApi")
	StandardMessageInfoQueryServiceForApi standardMessageInfoQueryServiceForApi;

	@Autowired
	StdMessageManService stdMessageManService;

	@Autowired
	StandardMessageInfoService standardMessageInfoService;

	@Autowired
	StdMessageUIMapper stdMessageUIMapper;

	@Autowired
	EaiMsgManService eaiMsgManService;

	@Autowired
	ServiceMessageUIMapper serviceMessageUIMapper;

	@Autowired
	SequenceService sequenceService;

	@Transactional(readOnly = false, transactionManager = "transactionManager")
	public Page<InterfaceUI> selectList(EAIMessageUISearch eaiMessageUISearch, Pageable pageable, String sortname,  String sortorder) {
		Page<Tuple> tuples = eaiMessageService.selectList(eaiMessageUISearch, pageable, sortname, sortorder);

		return tuples.map(tuple -> {
			EAIMessageEntity eaiMessageEntity = tuple.get(QEAIMessageEntity.eAIMessageEntity);
			String psvsysadptrbzwkgroupname = StringUtils
					.getStringValue(tuple.get(QServiceMessageEntity.serviceMessageEntity.psvsysadptrbzwkgroupname), "");
			String strIo = "I";
			String strDivCd = eaiMessageEntity.getEaisvcname().substring(eaiMessageEntity.getEaisvcname().length() - 2,
					eaiMessageEntity.getEaisvcname().length());

			if (strDivCd.equals("S2") || strDivCd.equals("R2")) {
				strIo = "O";
			}

			InterfaceUI interfaceUI = interfaceManUIMapper.toVoWithoutChildren(eaiMessageEntity);
			interfaceUI.setIo(strIo);
			if (!"".equals(psvsysadptrbzwkgroupname)) {
				interfaceUI.setToName(psvsysadptrbzwkgroupname.substring(1, 4));
			} else {
				interfaceUI.setToName(psvsysadptrbzwkgroupname);
			}

			return interfaceUI;
		});
	}

	public InterfaceUI selectDetail(String eaiSvcName) {

		InterfaceUI interfaceUI = eaiMessageService.findById(eaiSvcName).map(interfaceManUIMapper::toVo)
				.orElse(new InterfaceUI());

		String strSvcMotivUseDstcd = "";

		List<ServiceMessageUI> listServiceMessagUI = interfaceUI.getServiceMessages();

		if (listServiceMessagUI != null && listServiceMessagUI.size() > 0) {
			for (int i = 0; i < listServiceMessagUI.size(); i++) {
				if (i == 0) {
					if ("SYNC".equals(interfaceUI.getSvcMotivUseDstcd())
							&& "SYNC".equals(listServiceMessagUI.get(i).getPsvIntfacDsticName())) {
						strSvcMotivUseDstcd = "SYNC";
					} else if ("ASYN".equals(interfaceUI.getSvcMotivUseDstcd())
							&& "ASYN".equals(listServiceMessagUI.get(i).getPsvIntfacDsticName())) {
						strSvcMotivUseDstcd = "ASYN";
					} else if ("SYNC".equals(interfaceUI.getSvcMotivUseDstcd())
							&& "ASYN".equals(listServiceMessagUI.get(i).getPsvIntfacDsticName())) {
						strSvcMotivUseDstcd = "SYNC_ASYN";
					} else if ("ASYN".equals(interfaceUI.getSvcMotivUseDstcd())
							&& "SYNC".equals(listServiceMessagUI.get(i).getPsvIntfacDsticName())) {
						strSvcMotivUseDstcd = "ASYN_SYNC";
					}

					interfaceUI.setToAdapter(listServiceMessagUI.get(i).getPsvSysAdptrBzwkGroupName());
					interfaceUI.setLayoutMappingName(listServiceMessagUI.get(i).getChngMsgIdName());
				} else if (i == 1) {
					interfaceUI.setExtAdpater(listServiceMessagUI.get(i).getPsvSysAdptrBzwkGroupName());
				}
			}
		}

		interfaceUI.setSvcMotivUseDstcd(strSvcMotivUseDstcd);

		String strServiceId = "";
		String strBzwkSvcKeyName = "";
		Optional<StandardMessageInfo> optional = standardMessageInfoQueryServiceForApi.findByEaiSvcName(eaiSvcName);
		if (optional.isPresent()) {
			StandardMessageInfo standardMessageInfo = optional.get();
			List<StandardMessageItem> listStdMsgItem = standardMessageInfo.getStandardMessageItems();

			for (StandardMessageItem tmpItem : listStdMsgItem) {
				if ("INTERFACE_COMMON.API_PATH".equals(tmpItem.getId().getColumnname())) {
					strServiceId = tmpItem.getColumnvalue().toString();
					strBzwkSvcKeyName = tmpItem.getId().getBzwksvckeyname();
				}
			}
		}

		if ("FEP".equals(DataSourceContextHolder.getDataSourceType().getName())) {
			setIoBySuffix(interfaceUI);
		} else {
			// FEP 이외에는 당발로 고정
			interfaceUI.setIo("I");
		}

		interfaceUI.setServiceId(strServiceId);
		interfaceUI.setBzwkSvcKeyName(strBzwkSvcKeyName);
		if (!interfaceUI.getServiceMessages().isEmpty()
				&& !interfaceUI.getServiceMessages().get(0).getEaiReferenceMessages().isEmpty()) {
			interfaceUI.setLayoutMappingName(
					interfaceUI.getServiceMessages().get(0).getEaiReferenceMessages().get(0).getRefMsgIdName());
		} else {
			interfaceUI.setLayoutMappingName("");
		}

		Page<FieldExtractInfoUI> pgBzwkFldName = fieldExtractInfoService.selectList(eaiSvcName, Pageable.unpaged());
		List<FieldExtractInfoUI> arrBzwkFldName = new ArrayList<FieldExtractInfoUI>();

		if (pgBzwkFldName != null && pgBzwkFldName.hasContent()) {
			arrBzwkFldName = pgBzwkFldName.getContent();

			for (int i = 0; i < arrBzwkFldName.size(); i++) {
				if (i == 0) {
					interfaceUI.setBzwkFldName1(arrBzwkFldName.get(i).getBzwkFldName());
				} else if (i == 1) {
					interfaceUI.setBzwkFldName2(arrBzwkFldName.get(i).getBzwkFldName());
				}
			}
		}
		if (!DataSourceContextHolder.getDataSourceType()
				.equals(DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.FEP))) {
			interfaceUI.setSourceSystem(KakaoCardInterfaceNamingRule.getSourceFromIntfId(eaiSvcName));
			interfaceUI.setTargetSystem(KakaoCardInterfaceNamingRule.getTargetFromIntfId(eaiSvcName));
		}

		return interfaceUI;
	}

	private void setIoBySuffix(InterfaceUI interfaceUI) {
		if (!Objects.isNull(interfaceUI.getEaiSvcName())) {
			String eaiSvcName = interfaceUI.getEaiSvcName();
			if (eaiSvcName.endsWith("S1") || eaiSvcName.endsWith("R2")) {
				interfaceUI.setIo("O");
			} else if (eaiSvcName.endsWith("S2") || eaiSvcName.endsWith("R1")) {
				interfaceUI.setIo("I");
			} else {
				interfaceUI.setIo("error");
			}
		} else {
			interfaceUI.setIo("eaisvcname null");
		}
	}

	public void update(InterfaceUI interfaceUI) throws Exception {

		createInterfaceJummun(interfaceUI);
	}

	public String insert(InterfaceUI interfaceUI) throws Exception {
		// 1.중복체크
		Optional<EAIMessageEntity> dupCheck = eaiMessageService.findById(interfaceUI.getEaiSvcName());
		if (dupCheck.isPresent()) {
			String bzwkDstcd = (String) dupCheck.get().getEaibzwkdstcd();
			throw new BizException("업무명[" + bzwkDstcd + "]로 이미 등록된 인터페이스입니다.\n조회가 되지 않을 시 담당자에게 문의바랍니다.");
		}

		// 2.등록
		createInterfaceJummun(interfaceUI);
		return null;
	}

	public void delete(InterfaceUI interfaceUI) throws Exception {

		// 1.추적관리필드 삭제
		fieldExtractInfoService.delete(interfaceUI.getEaiSvcName(), "TR");

		// 2.참조메세지ID 삭제
		// 3.EAI메시지 삭제
		eaiMsgManService.delete(interfaceUI.getEaiSvcName());

		// 4.내부표준전문 삭제
		if (interfaceUI.getBzwkSvcKeyName() != null) {
			Optional<StandardMessageInfo> standardMessageInfo = standardMessageInfoService
					.findById(interfaceUI.getBzwkSvcKeyName());
			if (standardMessageInfo.isPresent()) {
				standardMessageInfoService.delete(standardMessageInfo.get());
			}
		}
	}

//	public HashMap selectCombo(String userId) throws Exception {
//		HashMap paramMap = new HashMap();
//		paramMap.put("userId", userId);
// 
//		// 전체 목록수 얻기
//		List list = bizDao.selectUserBizCodes(paramMap);
//		
//		HashMap map = new HashMap();
//
//		map.put("bizList", list);
//
//		return map;
//	}
//	public HashMap selectDetailCombo(String userId) throws Exception {
//		HashMap paramMap = new HashMap();
//		paramMap.put("userId", userId);
// 
//		// 업무구분
//		List listBiz = bizDao.selectUserBizCodes(paramMap);
//
//		// 당타발구분
//		List<ComboVo> listIo = comboService.getFromCode("IO_TYPE");
//
//		// 전문요청구분
//		List<ComboVo> listReqRes = comboService.getFromCode("REQRES_TYPE");
//		// 송수신방법
//		List<ComboVo> listSyncAsync = comboService.getFromCode("SYNCASYNC_TYPE");
//
//		// 거래흐름(INBOUND);
//		paramMap = new HashMap();
//		paramMap.put("adptrIoDstcd", "IN");
//		List listFrom = adapterDao.selectListCombo(paramMap);
//		
//		//거래흐름(OUTBOUND);
//		paramMap = new HashMap();
//		paramMap.put("adptrIoDstcd", "OU");
//		List listTo = adapterDao.selectListCombo(paramMap);
//		//거래흐름(ASBOUND);
//		paramMap = new HashMap();
//		paramMap.put("adptrIoDstcd", "OU");
//		paramMap.put("asyncDstCd", "As");
//		List listExt = adapterDao.selectListCombo(paramMap);
//		
//		HashMap map = new HashMap();
//
//		map.put("bizList", listBiz);
//		map.put("ioList", listIo);
//		map.put("reqResList", listReqRes);
//		map.put("syncAsyncList", listSyncAsync);
//		map.put("fromList", listFrom);
//		map.put("toList", listTo);
//		map.put("extList", listExt);
//
//		return map;
//	}	
	public List<AdapterGroupUI> selectAdapterCombo(String adptrIoDstcd) {
		List<AdapterGroupUI> selectAdapterGroup = adapterManService.selectListComboForAdptrIoDstcd(adptrIoDstcd);
		List<AdapterGroupUI> resultList = new ArrayList<AdapterGroupUI>();

		for (AdapterGroupUI tmpAdapter : selectAdapterGroup) {
			if ("1".equals(tmpAdapter.getAdptruseyn())) {
				resultList.add(tmpAdapter);
			}
		}

		return resultList;
	}

	public String createInterfaceJummun(InterfaceUI interfaceUI) throws Exception {
		logger.info("-------------------<< createInterfaceJummun >>----------------------------");
		logger.debug("{}", interfaceUI);
		logger.info("-------------------<< session 값체크>>----------------------------");

		boolean isOnline = false;
		for (DataSourceType ds : DataSourceTypeManager.getOnlineDataSourceTypes()) {
			if (ds.getName().equals(DataSourceContextHolder.getDataSourceType().getName())) {
				isOnline = true;
				break;
			}
		}

		if (!isOnline) {
			throw new BizException("로그인 오류 (재로그인 하시기 바랍니다.)");
		}

		String currentDatasourceDstCd = DataSourceContextHolder.getDataSourceType().getName().substring(0, 1);
		interfaceUI.setEaiSevrDstcd(currentDatasourceDstCd);
		interfaceUI.setAuthor(SessionManager.getLoginVo().getUserId());
		interfaceUI.setUseYn("1");
		interfaceUI.setVerInfo("0");
		interfaceUI.setTranType("R");

		logger.info("-1. 내부 표준 전문 INSERT ----------------------------------------------------");
		// 1. 내부 표준 전문 INSERT
		// 비표준에서 표준으로 가는 경우 표준으로 전환하기 위한 정보 이므로 내부로 갈 때만 처리
		if (!"SYNC_ASYN".equals(interfaceUI.getSvcMotivUseDstcd()) || !(interfaceUI.getEaiSvcName()).endsWith("R01")) { // EAI
																														// :
																														// SY_AS
																														// R01의
																														// toAdapter는
																														// 더미
			if (interfaceUI.getFromAdapter() == null || interfaceUI.getFromAdapter().isEmpty()
					|| interfaceUI.getToAdapter() == null || interfaceUI.getToAdapter().isEmpty()) {
				throw new Exception("INBOUND/OUTBOUND 설정이 되지 않았습니다.");
			}
		}

		AdapterGroupUI adapterGroup = new AdapterGroupUI();

		try {
			adapterGroup = adapterManService.selectDetail(interfaceUI.getFromAdapter());
		} catch (Throwable e) {
			throw new Exception("INBOUND어댑터 오류입니다.");
		}
		if (!Keys.IF_STANDARD.equals(adapterGroup.getAdptrmsgptrncd())) { // 내부표준이 아니면 처리
			if (interfaceUI.getServiceId().isEmpty()) {
				throw new Exception("내부표준전문 생성 오류!(입력전문ID null)");
			}
			if (interfaceUI.getBzwkSvcKeyName().isEmpty()) {
				throw new Exception("내부표준전문 생성 오류!(업무추출키 null)");
			}

			if ("S".equals(interfaceUI.getSplizDmndDstcd()) && "".equals(interfaceUI.getServiceId().trim())) { // Send(요청)의
																												// 경우만
				throw new Exception("내부표준전문 생성 오류!(입력전문ID space)");
			}
			if ("".equals(interfaceUI.getBzwkSvcKeyName().trim())) {
				throw new Exception("내부표준전문 생성 오류!(업무추출키 space)");
			}

			// 기존에 데이터가 없을경우 insert 있을 경우 update
			Optional<StandardMessageInfo> standardMessageInfo = standardMessageInfoService
					.findById(interfaceUI.getBzwkSvcKeyName());

			if (standardMessageInfo.isPresent()) {
				StdMessageUI stdMessageUI = new StdMessageUI();
				Map<String, Object> paramMap = new HashMap<String, Object>();
				String strDirection = interfaceUI.getEaiSvcName().substring(interfaceUI.getEaiSvcName().length() - 1,
						interfaceUI.getEaiSvcName().length());

				stdMessageUI.setBzwkSvcKeyName(interfaceUI.getBzwkSvcKeyName());
				stdMessageUI.setEaiSvcName(interfaceUI.getEaiSvcName());
				stdMessageUI.setEaiTranName(interfaceUI.getEaiTranName());
				stdMessageUI.setEaiSendRecv(interfaceUI.getSplizDmndDstcd());
				stdMessageUI.setEaiDirection(strDirection);

				paramMap.put("bzwksvckeyname", interfaceUI.getBzwkSvcKeyName());
				paramMap.put("columnname", "INTERFACE_COMMON.API_PATH");
				paramMap.put("columnvalue", interfaceUI.getServiceId());

				stdMessageManService.update(paramMap, stdMessageUI);
			} else {
				StdMessageUI stdMessageUI = new StdMessageUI();
				StdMessageItemUI stdMessageItemUI = new StdMessageItemUI();
				List<StdMessageItemUI> listStdMessageItemUI = new ArrayList<>();
				String strDirection = interfaceUI.getEaiSvcName().substring(interfaceUI.getEaiSvcName().length() - 1,
						interfaceUI.getEaiSvcName().length());

				stdMessageUI.setBzwkSvcKeyName(interfaceUI.getBzwkSvcKeyName());
				stdMessageUI.setEaiSvcName(interfaceUI.getEaiSvcName());
				stdMessageUI.setEaiTranName(interfaceUI.getEaiTranName());
				stdMessageUI.setEaiSendRecv(interfaceUI.getSplizDmndDstcd());
				stdMessageUI.setEaiDirection(strDirection);

				stdMessageItemUI.setBzwksvckeyname(interfaceUI.getBzwkSvcKeyName());
				stdMessageItemUI.setColumnname("INTERFACE_COMMON.API_PATH");
				stdMessageItemUI.setColumnvalue(interfaceUI.getServiceId());
				listStdMessageItemUI.add(stdMessageItemUI);
				stdMessageUI.setStandardMessageItems(listStdMessageItemUI);

				StandardMessageInfo insStandardMessageInfo = stdMessageUIMapper.toEntity(stdMessageUI);
				standardMessageInfoService.save(insStandardMessageInfo);
			}

			logger.debug("TEST");

		} else {
			// 표준전문일 경우
			Optional<StandardMessageInfo> standardMessageInfo = standardMessageInfoService
					.findById(interfaceUI.getEaiTranName().replaceAll("_", "") + interfaceUI.getSplizDmndDstcd()
							+ interfaceUI.getStndTelgmWtinExtnlDstcd());

			if (standardMessageInfo.isPresent()) {
				stdMessageManService.delete(interfaceUI.getBzwkSvcKeyName());
			}
		}

		logger.info("-2. EAI메세지 INSERT -------------------------------------------------------");
		// 2. EAI메세지 INSERT
		///////////////////////////////////////////////////////////////////////////////////////////
		// FlowControl 라우팅명 셋팅 - B2B 라우터 설정 확인 ( rms.flowcontrol.b2bfc )
		///////////////////////////////////////////////////////////////////////////////////////////

		String b2bfcs = monitoringContext.getStringProperty(MonitoringContext.RMS_FLOWCONTROL_B2BFC, "");
		if (b2bfcs.indexOf(interfaceUI.getEaiTranName().substring(0, 3)) > -1
				&& interfaceUI.getEaiSvcName().endsWith("2")) {
			interfaceUI.setFlowCtrlRoutName(InterfaceKeys.FCR_B2B);
		} else {
			if (interfaceUI.getEaiSvcName().endsWith("R1")) {
				interfaceUI.setFlowCtrlRoutName(InterfaceKeys.FCR_C2R);
			} else {
				interfaceUI.setFlowCtrlRoutName(InterfaceKeys.FCR_BAS);
			}
		}

		///////////////////////////////////////////////////////////////////////////////////////////
		// FlowControl 라우팅명 셋팅 - 큐 설정 확인 ( rms.flowcontrol.queue.[EAI/FEP].[001~012] )
		///////////////////////////////////////////////////////////////////////////////////////////
		for (int i = 1; i <= 12; i++) {
			String propKey = MonitoringContext.RMS_FLOWCONTROL_QUEUE + "."
					+ DataSourceContextHolder.getDataSourceType().getName() + "." + StringUtils.leftPad("" + i, 3, "0");
			String queues = monitoringContext.getStringProperty(propKey, "");
			if (queues.indexOf(interfaceUI.getEaiTranName().substring(0, 3) + interfaceUI.getSplizDmndDstcd()
					+ interfaceUI.getStndTelgmWtinExtnlDstcd()) > -1) {
				interfaceUI.setFlowCtrlRoutName(
						interfaceUI.getFlowCtrlRoutName() + "_" + StringUtils.leftPad("" + i, 3, "0"));
				break;
			}
		}

		///////////////////////////////////////////////////////////////////////////////////////////
		// FailOver 설정 - FailOver 대상(당발요청S2,타발응답R2)이면 사용함으로 셋팅 (
		/////////////////////////////////////////////////////////////////////////////////////////// rms.failover.target.[EAI/FEP]
		/////////////////////////////////////////////////////////////////////////////////////////// )
		///////////////////////////////////////////////////////////////////////////////////////////
		interfaceUI.setFailOver(false);
		if (!(DataSourceTypeManager.EAI.equals(DataSourceContextHolder.getDataSourceType().getName())
				&& "2".equals(interfaceUI.getStndTelgmWtinExtnlDstcd()))
				|| DataSourceTypeManager.EAI.equals(DataSourceContextHolder.getDataSourceType().getName())) {
			String propKey = MonitoringContext.RMS_FAILOVER_TARGET + "."
					+ DataSourceContextHolder.getDataSourceType().getName();
			String failOvers = monitoringContext.getStringProperty(propKey, "");
			if (failOvers.indexOf(interfaceUI.getEaiTranName().substring(0, 3)) > -1) {
				interfaceUI.setFailOver(true);
			}
		}

		// 현재시간 구해서 최종수정시각 추가
//        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
//        interfaceUI.setEaiLastAmndYMS(LocalDateTime.parse(String.valueOf(System.currentTimeMillis()), DateTimeFormatter.ofPattern( "yyyyMMddHHmmss")));

		// interfaceUI.setEaiLastAmndYMS(DateUtil.getDateTimeMilliSecound());

		// 화면에서 가져오지 않은 값 기존 값으로 대체
		// insert/update에 사용할 대체 값 생성
		EAIMessageEntity insertObj = new EAIMessageEntity();
		Optional<EAIMessageEntity> beforeEAIMessageEntity = eaiMessageService.findById(interfaceUI.getEaiSvcName());
		Boolean isUpdate = false;
		if (beforeEAIMessageEntity.isPresent()) {

			EAIMessageEntity eaiMessageEntity = beforeEAIMessageEntity.get();
			interfaceUI.setFlowCtrlRoutName(!interfaceUI.getFlowCtrlRoutName().isEmpty()
					? interfaceUI.getFlowCtrlRoutName()
					: eaiMessageEntity.getFlowctrlroutname().isEmpty() ? "" : eaiMessageEntity.getFlowctrlroutname());
			interfaceUI.setDmndErrChngIdName(!interfaceUI.getDmndErrChngIdName().isEmpty()
					? interfaceUI.getDmndErrChngIdName()
					: eaiMessageEntity.getDmnderrchngidname().isEmpty() ? "" : eaiMessageEntity.getDmnderrchngidname());
			interfaceUI.setRspnsErrChngIdName(!interfaceUI.getRspnsErrChngIdName().isEmpty()
					? interfaceUI.getRspnsErrChngIdName()
					: eaiMessageEntity.getFlowctrlroutname().isEmpty() ? "" : eaiMessageEntity.getFlowctrlroutname());
			interfaceUI.setRspnsErrChngIdName(
					!interfaceUI.getRspnsErrChngIdName().isEmpty() ? interfaceUI.getRspnsErrChngIdName()
							: eaiMessageEntity.getRspnserrchngidname().isEmpty() ? ""
									: eaiMessageEntity.getRspnserrchngidname());
			interfaceUI.setEaiSevrDstcd(!interfaceUI.getEaiSevrDstcd().isEmpty() ? interfaceUI.getEaiSevrDstcd()
					: eaiMessageEntity.getEaisevrdstcd().isEmpty() ? "" : eaiMessageEntity.getEaisevrdstcd());
			interfaceUI.setEaiGroupCoCd(!interfaceUI.getEaiGroupCoCd().isEmpty() ? interfaceUI.getEaiGroupCoCd()
					: eaiMessageEntity.getEaigroupcocd().isEmpty() ? "" : eaiMessageEntity.getEaigroupcocd());
			interfaceUI.setFlowCtrlRoutName(!interfaceUI.getFlowCtrlRoutName().isEmpty()
					? interfaceUI.getFlowCtrlRoutName()
					: eaiMessageEntity.getFlowctrlroutname().isEmpty() ? "" : eaiMessageEntity.getFlowctrlroutname());
			interfaceUI.setModfiMgtStusDstcd(!interfaceUI.getModfiMgtStusDstcd().isEmpty()
					? interfaceUI.getModfiMgtStusDstcd()
					: eaiMessageEntity.getModfimgtstusdstcd().isEmpty() ? "" : eaiMessageEntity.getModfimgtstusdstcd());
			interfaceUI.setTranType(!interfaceUI.getTranType().isEmpty() ? interfaceUI.getTranType()
					: eaiMessageEntity.getTrantype().isEmpty() ? "" : eaiMessageEntity.getTrantype());
			interfaceUI.setUseYn(!interfaceUI.getUseYn().isEmpty() ? interfaceUI.getUseYn()
					: eaiMessageEntity.getUseyn().isEmpty() ? "" : eaiMessageEntity.getUseyn());

			// update일 경우 기존 entity 를 조회하여 set
			insertObj = eaiMessageService.getById(interfaceUI.getEaiSvcName());
			isUpdate = true;
		}

		// 기동 어뎁터
		// Async 인 경우 As, Sync인 경우 Sy
		// SOCKET 인 경우 처리 후 개별 수정 하는 것으로 !
		// he01, he02 동시에 interfaceUI 를 사용해야 하기 때문에 구분코드를 type 에 임시 저장하고 해당 값을 사용
		String type = interfaceUI.getSvcMotivUseDstcd();
		if ("ASYN".equals(type) || "SYNC".equals(type)) {
			interfaceUI.setSvcMotivUseDstcd(type);
		} else if ("ASYN_SYNC".equals(type)) {
			interfaceUI.setSvcMotivUseDstcd("SYNC");
		} else if ("SYNC_ASYN".equals(type)) {
			interfaceUI.setSvcMotivUseDstcd("ASYN");
		}

		interfaceUI.setSvcHMSEonot("0");
		interfaceUI.setSvcPrcesDsticName("SINGLE");
		interfaceUI.setIntgraDsticName("ONLINE");
		interfaceUI.setSvcBfClmnLogYn("0");
		interfaceUI.setGstatSysAdptrBzwkGroupName(interfaceUI.getFromAdapter());
		interfaceUI.setSevrLogLvelNo(0);
		interfaceUI.setSvcLogLvelNo(3);

		// serviceMessages 값을 set 필요함 기존값을 그대로 가지고오고 상황에 따라 값을 변경하여 다시 집어넣는다.
		// svcprcssno 가 1 개인 경우 2 개인 경우가 발생할 수 있음
		ServiceMessageUI serviceMessageUI = new ServiceMessageUI();

		if ("ASYN".equals(type) || "SYNC".equals(type)) {
			serviceMessageUI.setPsvIntfacDsticName(type);
		} else if ("ASYN_SYNC".equals(type)) {
			serviceMessageUI.setPsvIntfacDsticName("SYNC");
		} else if ("SYNC_ASYN".equals(type)) {
			serviceMessageUI.setPsvIntfacDsticName("ASYN");
		}

		serviceMessageUI.setEaiSvcName(interfaceUI.getEaiSvcName());
		serviceMessageUI.setSvcPrcssNo(1);
		serviceMessageUI.setPsvSysBzwkDstcd(interfaceUI.getEaiBzwkDstcd());
		serviceMessageUI.setPsvsysidname("EAIDOM");
		serviceMessageUI.setPsvSysSvcDsticName(" ");
		serviceMessageUI.setFlovrYn(interfaceUI.getFailOver() ? "1" : "0");
		serviceMessageUI.setChngEonot("0");
		serviceMessageUI.setChngMsgIdName("");
		serviceMessageUI.setBascRspnsMsgCmprCtnt("");
		serviceMessageUI.setBascRspnsChngEonot("0");
		serviceMessageUI.setBascRspnsChngMsgIdName("");
		serviceMessageUI.setErrRspnsMsgCmprCtnt("");
		serviceMessageUI.setErrRspnsChngEonot("0");
		serviceMessageUI.setErrRspnsChngMsgIdName("");
		serviceMessageUI.setNextSvcPrcssNo(1);
		serviceMessageUI.setToutVal(Long.parseLong("60"));
		serviceMessageUI.setCmpenSvcPrcssDsticName("");
		serviceMessageUI.setSupplDelYn("0");
		serviceMessageUI.setHdrCtrlDstcd("01");
		serviceMessageUI.setHdrRefClsName("");
		serviceMessageUI.setRestOption("");
		serviceMessageUI.setPsvSysAdptrBzwkGroupName(interfaceUI.getToAdapter());

		if ("SYNC_ASYN".equals(type) && interfaceUI.getEaiSvcName().endsWith("R1")) { // EAI에 한함
			serviceMessageUI.setPsvSysAdptrBzwkGroupName(" ");
			serviceMessageUI.setOutbndRoutName("HTTPOUT");
		} else {
			if ("NET".equals(interfaceUI.getToAdapter().substring(8, 11))) {
				serviceMessageUI.setOutbndRoutName("SOCKETOUT");
			} else if ("HTT".equals(interfaceUI.getToAdapter().substring(8, 11))) {
				serviceMessageUI.setOutbndRoutName("HTTPOUT");
			}
		}

		serviceMessageUI.setEaiReferenceMessages(new ArrayList<EAIReferenceMessageUI>());
		serviceMessageUI.setCondPerRtgInfos(new ArrayList<CondPerRtgInfoUI>());

		logger.info("-3. 참조메시지ID INSERT ----------------------------------------------------");
		if (interfaceUI.getLayoutMappingName() != null && !interfaceUI.getLayoutMappingName().trim().isEmpty()) {
			// EAIReferenceMessageUI 가 존재함 해당 값 insert
			EAIReferenceMessageUI eaiReferenceMessageUI = new EAIReferenceMessageUI();

			eaiReferenceMessageUI.setEaiSvcName(interfaceUI.getEaiSvcName());
			eaiReferenceMessageUI.setSvcPrcssNo(1);
			eaiReferenceMessageUI.setRefMsgIdNo(1);
			eaiReferenceMessageUI.setRefMsgIdName(interfaceUI.getLayoutMappingName().replaceAll(",", ";"));
			serviceMessageUI.getEaiReferenceMessages().add(eaiReferenceMessageUI);
		}

		logger.debug("--------------------------------------------------------------------------");
		interfaceUI.setServiceMessages(new ArrayList<ServiceMessageUI>());
		interfaceUI.getServiceMessages().add(serviceMessageUI);

//        if( isUpdate == true ){
//            interfaceUI.setServiceMessages(new ArrayList<ServiceMessageUI>());
//            interfaceUI.getServiceMessages().add(serviceMessageUI);
//        } else {
//            insertObj.setServiceMessages(new ArrayList<ServiceMessageEntity>());
//            ServiceMessageEntity insSrvMessage = serviceMessageUIMapper.toEntity(serviceMessageUI);
//            insSrvMessage.setEaimessage(insertObj);
//            insertObj.getServiceMessages().add(insSrvMessage);
//        }

		if ("ASYN_SYNC".equals(type)) {
			ServiceMessageUI subServiceMessageUI = new ServiceMessageUI();

			if ("S".equals(interfaceUI.getExtAdpater().substring(12, 13))) {
				subServiceMessageUI.setPsvIntfacDsticName("SYNC");
			} else {
				subServiceMessageUI.setPsvIntfacDsticName("ASYN");
			}

			subServiceMessageUI.setEaiSvcName(interfaceUI.getEaiSvcName());
			subServiceMessageUI.setSvcPrcssNo(2);
			subServiceMessageUI.setPsvSysBzwkDstcd(interfaceUI.getEaiBzwkDstcd());
			subServiceMessageUI.setPsvsysidname("EAIDOM");
			subServiceMessageUI.setPsvSysSvcDsticName(" ");
			subServiceMessageUI.setFlovrYn(interfaceUI.getFailOver() ? "1" : "0");
			subServiceMessageUI.setChngEonot("0");
			subServiceMessageUI.setChngMsgIdName("");
			subServiceMessageUI.setBascRspnsMsgCmprCtnt("");
			subServiceMessageUI.setBascRspnsChngEonot("0");
			subServiceMessageUI.setBascRspnsChngMsgIdName("");
			subServiceMessageUI.setErrRspnsMsgCmprCtnt("");
			subServiceMessageUI.setErrRspnsChngEonot("0");
			subServiceMessageUI.setErrRspnsChngMsgIdName("");
			subServiceMessageUI.setNextSvcPrcssNo(1);
			subServiceMessageUI.setToutVal(Long.parseLong("60"));
			subServiceMessageUI.setCmpenSvcPrcssDsticName("");
			subServiceMessageUI.setSupplDelYn("0");
			subServiceMessageUI.setHdrCtrlDstcd("01");
			subServiceMessageUI.setHdrRefClsName("");
			subServiceMessageUI.setRestOption("");
			subServiceMessageUI.setPsvSysAdptrBzwkGroupName(interfaceUI.getExtAdpater());
			subServiceMessageUI
					.setOutbndRoutName(interfaceUI.getExtAdpater().indexOf("NET") > -1 ? "SOCKETOUT" : "HTTPOUT");

			subServiceMessageUI.setEaiReferenceMessages(new ArrayList<EAIReferenceMessageUI>());
			subServiceMessageUI.setCondPerRtgInfos(new ArrayList<CondPerRtgInfoUI>());
			interfaceUI.getServiceMessages().add(subServiceMessageUI);
		}

		interfaceManUIMapper.updateEntity(interfaceUI, insertObj);

		if (isUpdate == true) {
			insertObj.getServiceMessages().clear();
			ServiceMessageEntity insSrvMessage = serviceMessageUIMapper.toEntity(serviceMessageUI);
			insSrvMessage.setEaimessage(insertObj);
			insertObj.getServiceMessages().add(insSrvMessage);
		} else {
			insertObj.setServiceMessages(new ArrayList<ServiceMessageEntity>());
			ServiceMessageEntity insSrvMessage = serviceMessageUIMapper.toEntity(serviceMessageUI);
			insSrvMessage.setEaimessage(insertObj);
			insertObj.getServiceMessages().add(insSrvMessage);
		}

		eaiMessageService.save(insertObj);

//        dao.mergeToHE01(vo);
//        dao.mergeToHE02(vo);
//        logger.info("-3. 참조메시지ID INSERT ----------------------------------------------------");
//        // 3. 참조메시지ID INSERT
//        //if( vo.get("layoutMappingName") != null && !"".equals(((String)vo.get("layoutMappingName")).trim())) {   //삭제
//        //transMapping.appContext = this.appContext;
//        HashMap<String,Object> transform = new HashMap<String,Object>();
//        transform.put("eaiSvcName", interfaceUI.getEaiSvcName());
//        transform.put("refMsgIdName",( interfaceUI.getLayoutMappingName().replaceAll(",", ";")));
//        transMapping.insertRefMsgID(transform);
//        //if( rts <= 0) {
//        //   throw new BizException("참조메세지ID 생성 실패");
//        //}
//        //}
//
//        logger.debug("--------------------------------------------------------------------------");
		logger.info("-4. 추적관리필드 INSERT -----------------------------------------------------");
		// 4. 추적관리필드 INSERT

		Page<FieldExtractInfoUI> fieldExtractInfoUIList = fieldExtractInfoService
				.selectList(interfaceUI.getEaiSvcName(), Pageable.unpaged());

		if (!fieldExtractInfoUIList.isEmpty()) {
			fieldExtractInfoUIList.forEach(e -> fieldExtractInfoService.delete(e.getEaiSvcName(), e.getEtractDstcd()));
		}

		if (interfaceUI.getLayoutMappingName() != null && !"".equals(interfaceUI.getLayoutMappingName())) {

			FieldExtractInfoUI fieldExtractInfoUI = new FieldExtractInfoUI();

			fieldExtractInfoUI.setEaiSvcName(interfaceUI.getEaiSvcName());
			fieldExtractInfoUI.setEtractDstcd("TR");
			fieldExtractInfoUI.setFldprcssno(1);
			fieldExtractInfoUI.setMsgDstcd("ASC");

			fieldExtractInfoUI.setBzwkFldName(StringUtils.split(interfaceUI.getLayoutMappingName(), ",")[0]);
			int count = 0;
			if (interfaceUI.getBzwkFldName1() != null && !"".equals(StringUtils.trim(interfaceUI.getBzwkFldName1()))) {
				count++;
			}
			if (interfaceUI.getBzwkFldName2() != null && !"".equals(StringUtils.trim(interfaceUI.getBzwkFldName2()))) {
				count++;
			}
			String[][] bzwkFldArray = new String[count][3];
			String[] bzwkFldsArray = new String[count];
			if (interfaceUI.getBzwkFldName1() != null && !"".equals(StringUtils.trim(interfaceUI.getBzwkFldName1()))) {
				bzwkFldArray[0][0] = StringUtils.trim(interfaceUI.getBzwkFldName1());
				bzwkFldArray[0][1] = "0"; // StringUtils.getStringValue(vo.get("msgFldStartSituVal1"), "0");
				bzwkFldArray[0][2] = "0"; // StringUtils.getStringValue(vo.get("msgFldLen1"), "0");
				bzwkFldsArray[0] = StringUtils.trim(interfaceUI.getBzwkFldName1());
			}
			if (interfaceUI.getBzwkFldName2() != null && !"".equals(StringUtils.trim(interfaceUI.getBzwkFldName2()))) {
				bzwkFldArray[1][0] = StringUtils.trim(interfaceUI.getBzwkFldName2());
				bzwkFldArray[1][1] = "0"; // StringUtils.getStringValue(vo.get("msgFldStartSituVal2"), "0");
				bzwkFldArray[1][2] = "0"; // StringUtils.getStringValue(vo.get("msgFldLen2"), "0");
				bzwkFldsArray[1] = StringUtils.trim(interfaceUI.getBzwkFldName2());
			}
			StringBuilder sb = new StringBuilder();
			sb.append("bzwkFldArray :");
			for (String[] keys : bzwkFldArray) {
				for (String key : keys) {
					sb.append("[" + key + "],");
				}
				sb.append("\n");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("vo.getBzwkFldName1()=[" + interfaceUI.getBzwkFldName1() + "]");
				logger.debug("vo.getBzwkFldName2()=[" + interfaceUI.getBzwkFldName2() + "]");
				logger.debug("{}", sb);
			}
			fieldExtractInfoUI.setBzwkFldNames(bzwkFldsArray);

			fieldExtractInfoService.insert(fieldExtractInfoUI);
		}

		return "";
	}

	public String getIncresedInterfaceId(HashMap<String, String> paramMap) {

		String source = paramMap.get("source");
		String target = paramMap.get("target");

		String seqStr = String.format("%05d", 1);

		String strInsKey = KakaoCardInterfaceNamingRule.makeSeqKey(source, target);

		Optional<SequenceEntity> seqId = sequenceService.findById(strInsKey);

		if (seqId.isPresent()) {
			seqStr = String.format("%05d", seqId.get().getNext_val() + 1);
		} else {
			SequenceEntity insSeqEntity = new SequenceEntity();
			insSeqEntity.setSequence_name(strInsKey);
			insSeqEntity.setNext_val(1L);

			sequenceService.save(insSeqEntity);
		}

		return KakaoCardInterfaceNamingRule.sourceTargetToIntfId(source, target, seqStr);
	}

	public Page<InterfaceUI> selectPopList(Pageable pageable, String eaiSvcName, String serviceType) {
		Page<EAIMessageEntity> page = eaiMessageService.findAll(pageable, eaiSvcName);

		List<InterfaceUI> interfaceUIs = page.getContent().stream()
				.map(entity -> convertToInterfaceUI(entity, serviceType)).collect(Collectors.toList());

		return new PageImpl<>(interfaceUIs, pageable, page.getTotalElements());
	}

	private InterfaceUI convertToInterfaceUI(EAIMessageEntity entity, String serviceType) {
		InterfaceUI interfaceUI = new InterfaceUI();
		String getEaiSvcName = entity.getEaisvcname();

		interfaceUI.setEaiSvcName(getEaiSvcName);
		interfaceUI.setEaiBzwkDstcd(entity.getEaibzwkdstcd());
		interfaceUI.setEaiSvcDesc(entity.getEaisvcdesc());
		interfaceUI.setEaiTranName(getEaiSvcName.substring(0, getEaiSvcName.length() - 2));

		String lastTwoChars = getEaiSvcName.substring(getEaiSvcName.length() - 2);

		if ("EAI".equals(serviceType)) {
			interfaceUI.setIo(("S2".equals(lastTwoChars) || "R2".equals(lastTwoChars)) ? "O" : "I");
		} else {
			interfaceUI.setIo(("S2".equals(lastTwoChars) || "R1".equals(lastTwoChars)) ? "O" : "I");
		}

		interfaceUI.setSplizDmndDstcd(lastTwoChars.substring(0, 1)); // set S / R
		interfaceUI.setEaiSevrDstcd(entity.getEaisevrdstcd());

		return interfaceUI;
	}

}
