package com.eactive.eai.rms.onl.manage.rule.layoutsync;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.rms.onl.manage.rule.transform.TransformDao;
import com.eactive.eai.rms.onl.manage.rule.transform.TransformManService;
import com.eactive.eai.rms.onl.manage.serviceinfo.eaimsg.EaiMsgDao;

import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
class KJBTransformService {

	private static final Logger logger = LoggerFactory.getLogger(KJBTransformService.class);

	private final TransformDao transformDao;
	private final KJBLayoutDao layoutDao;

	// 참고메시지 id 를 얻기 위함.
	private final EaiMsgDao eaiMessageDAO;

	TransformManService transformManService;

	public String transactionLayoutToTransform(JSONObject json, String interfaceLayoutName, String serviceLayoutName)
			throws Exception {
		/*
		 * 인터페이스가 있는 지 확인 후 없으면 전문레이아웃변환매핑을 신규로 입력 한다. 있을 경우 추후 프로세스에 의해 정보가 업데이트 된다.
		 */

		JSONObject message = (JSONObject) json.get("Message");
		JSONObject header = (JSONObject) message.get("Header");
		JSONObject body = (JSONObject) message.get("Body");

		String interfaceCode = (String) body.get("interfaceCode");

		String srcLayoutName = null;
		String tgtLayoutName = null;

		JSONObject srcLayout = null;
		JSONObject tgtLayout = null;

		JSONArray layoutArray = (JSONArray) body.get("Layout");

		// interfaceCode에 해당하는 Layout 검색
		JSONObject interfaceLayout = (JSONObject) layoutArray.stream()
				.filter(j -> interfaceLayoutName.equals(((JSONObject) j).get("id"))).findFirst().get();
		JSONObject serviceLayout = (JSONObject) layoutArray.stream()
				.filter(j -> serviceLayoutName.equals(((JSONObject) j).get("id"))).findFirst().get();

		String cnvsnDesc = (String) body.get("interfaceDesc");

		String interfaceIdSuffix = null;
		String cnvsnType = null;

		if ("I".equals(interfaceLayout.get("ioType")) || ((String) interfaceLayout.get("id")).endsWith("S1")) {
			cnvsnType = "REQ";
		} else {
			cnvsnType = "RES";
		}

		if ("EAI".equals(interfaceLayout.get("usesystem"))) {
			// EAI
			if (interfaceCode.startsWith("EA"))// 비동기
			{
				interfaceIdSuffix = "REQ".equals(cnvsnType) ? "S1" : "R1";
			} else// 동기
			{
				interfaceIdSuffix = "REQ".equals(cnvsnType) ? "S1" : "S1";
			}

		} else if ("FEP".equals(interfaceLayout.get("usesystem"))) {
			// FEP
			// 당타발
			if (interfaceCode.startsWith("F1")) {
				// 타발
				interfaceIdSuffix = "REQ".equals(cnvsnType) ? "S1" : "R2";
			} else if (interfaceCode.startsWith("F2")) {
				// 당발
				interfaceIdSuffix = "REQ".equals(cnvsnType) ? "S2" : "R1";
			}
		}

		String cnvsnName = String.format("TRANSFORM_%s_%s%s_%s", body.get("bzSystemCode"), interfaceCode,
				interfaceIdSuffix, cnvsnType);

		if ("FEP".equals(interfaceLayout.get("usesystem")) || "REQ".equals(cnvsnType)) {
			srcLayoutName = interfaceLayoutName;
			srcLayout = interfaceLayout;

			tgtLayoutName = serviceLayoutName;
			tgtLayout = serviceLayout;
		} else {
			srcLayoutName = serviceLayoutName;
			srcLayout = serviceLayout;

			tgtLayoutName = interfaceLayoutName;
			tgtLayout = interfaceLayout;
		}

		HashMap<String, Object> params = new HashMap<>();
		params.put("cnvsnName", cnvsnName);

		Map<String, Object> fransformDetail = transformDao.selectDetail(params);

		if (fransformDetail == null) {
			insert(interfaceCode, cnvsnName, cnvsnDesc, cnvsnType);
		}

		HashMap param = new HashMap();
		param.put("loutName", srcLayoutName);
		List<HashMap<String, Object>> srcDataArray = layoutDao.selectItemPathList(param);
		param.put("loutName", tgtLayoutName);
		List<HashMap<String, Object>> tgtDataArray = layoutDao.selectItemPathList(param);

		HashMap[] list = new HashMap[srcDataArray.size()];

		for (int i = 0; i < srcDataArray.size(); i++) {
			String s = (String) ((HashMap<String, Object>) srcDataArray.get(i)).get("PATH");
			String t = (String) ((HashMap<String, Object>) tgtDataArray.get(i)).get("PATH");

			HashMap m = new HashMap();

			m.put("CNVSNCMDNAME", s);
			m.put("CNVSNRSULTITEMPATHNAME", t);
			m.put("CNVSNITEMBASCVAL", "");
			m.put("CNVSNITEMSERNO", i + 1);

			list[i] = m;
		}

		transaction(cnvsnName, interfaceCode, cnvsnDesc, srcLayoutName, tgtLayoutName, list, "false", cnvsnType);

		return cnvsnName;

	}

	public void insert(String eaiSvcName, String cnvsnName, String cnvsnDesc, String cnvsnType) {

		HashMap paramMap = new HashMap();
		paramMap.put("eaiSvcName", eaiSvcName);
		paramMap.put("cnvsnName", cnvsnName);
		paramMap.put("cnvsnType", cnvsnType);
		paramMap.put("cnvsnDesc", cnvsnDesc);
		paramMap.put("chngEonot", "1");// 0.미사용 1.사용
		// 1.EAI Message에 셋팅
		updateTransfromEaiSvcName(paramMap);
		// 2.EAI
		transformDao.insert(paramMap);

	}

	public void transaction(String cnvsnName, String eaiSvcName, String cnvsnDesc, String srcLayoutName,
			String tgtLayoutName, HashMap[] list, String chkForce, String cnvsnType) throws Exception {

		if (chkForce != null && "true".equals(chkForce)) {
			HashMap paramMap = new HashMap();
			paramMap.put("cnvsnName", cnvsnName);
			paramMap.put("eaiSvcName", eaiSvcName);
			paramMap.put("cnvsnType", cnvsnType);
			paramMap.put("chngEonot", "1");// 0.미사용 1.사용
			updateTransfromEaiSvcName(paramMap);
		}

		HashMap paramMap = new HashMap();
		// 1.변환 테이블 update
		paramMap.put("cnvsnName", cnvsnName);
		paramMap.put("cnvsnDesc", cnvsnDesc);
		transformDao.updateTransform(paramMap);
		// 2.변환 소스/결과 테이블 update
		paramMap = new HashMap();
		paramMap.put("cnvsnName", cnvsnName);
		transformDao.deleteTransformSourceResult(paramMap);

		// 2-1.SRC 등록
		paramMap.put("loutName", srcLayoutName);
		paramMap.put("sourcRsultDstcd", "SRC_LAYOUT");
		transformDao.insertTransformSourceResult(paramMap);

		// 2-2.TGT 등록
		paramMap.put("loutName", tgtLayoutName);
		paramMap.put("sourcRsultDstcd", "TGT_LAYOUT");
		transformDao.insertTransformSourceResult(paramMap);

		// 3.변환항목 테이블 update
		// -----------------------------------------------------------------------------
		// 임시코드 : 복합거래시 소스레이아웃을 추가로 등록되도록 임시 수정 (2018.06.26)
		// -----------------------------------------------------------------------------
		String layoutName = null;
		HashMap layoutParamMap = new HashMap();
		layoutParamMap.put("cnvsnName", cnvsnName);
		layoutParamMap.put("sourcRsultDstcd", "SRC_LAYOUT");

		HashMap layoutMap = new HashMap();
		// -----------------------------------------------------------------------------

		paramMap = new HashMap();
		paramMap.put("cnvsnName", cnvsnName);
		transformDao.deleteTransformItem(paramMap);
		for (int i = 0; i < list.length; i++) {
			paramMap.put("cnvsnCmdName", list[i].get("CNVSNCMDNAME"));
			paramMap.put("cnvsnRsultItemPathName", list[i].get("CNVSNRSULTITEMPATHNAME"));
			paramMap.put("cnvsnItemBascVal", Objects.toString(list[i].get("CNVSNITEMBASCVAL"), ""));
			paramMap.put("cnvsnItemSerno", list[i].get("CNVSNITEMSERNO"));

			transformDao.insertTransformItem(paramMap);
			// -----------------------------------------------------------------------------
			// 임시코드 : 복합거래시 소스레이아웃을 추가로 등록되도록 임시 수정 (2018.06.26)
			// -----------------------------------------------------------------------------
			logger.debug(">>> Check SRC_LAYOUT layoutName = " + layoutName);

			layoutName = extractLayoutName((String) list[i].get("CNVSNCMDNAME"));
			if (layoutName == null || srcLayoutName.equals(layoutName) || layoutMap.get(layoutName) != null) {
				// Do nothing
			} else {
				logger.debug(">>> Added SRC_LAYOUT layoutName = " + layoutName);
				layoutParamMap.put("loutName", layoutName);
				transformDao.insertTransformSourceResult(layoutParamMap);
				layoutMap.put(layoutName, layoutName);
			}
			// -----------------------------------------------------------------------------
		}

	}

	public void updateTransfromEaiSvcName(HashMap paramMap) {
		// String cnvsnType = null;
		HashMap map = new HashMap();
		String eaiSvcName = (String) paramMap.get("eaiSvcName");
		map.put("eaiSvcName", eaiSvcName);
		map.put("svcPrcssNo", "1");

		try {
			HashMap ifc = eaiMessageDAO.selectDetailSvc(map);

			if ("ASYN".equals((String) ifc.get("PSVINTFACDSTICNAME"))) {
				if (!"ERR".equals((String) paramMap.get("cnvsnType"))) {
					// cnvsnType = "REQ";
					/**
					 * 20200521. SYNC-ASYN 처리 추가
					 */
					HashMap ifmsg = eaiMessageDAO.selectDetail(map);
					String inboundSyncAsync = (String) ifmsg.get("SVCMOTIVUSEDSTCD");
					if ("SYNC".equals(inboundSyncAsync) == false) {
						paramMap.put("cnvsnType", "REQ");
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}

		transformDao.updateTransfromEaiSvcName(paramMap);
	}

	private String extractLayoutName(String path) {
		String layoutName = null;
		int sPos = 0;
		int ePos = 0;
		if (path == null || path.length() == 0)
			return null;

		sPos = path.lastIndexOf("(");
		if (sPos < 0) {
			sPos = 0;
		} else if (sPos > 0) {
			sPos = sPos + 1;
		}

		ePos = path.indexOf(".");
		if (ePos < 0)
			sPos = 0;

		if (ePos > 0 && ePos > sPos) {
			layoutName = path.substring(sPos, ePos);
			layoutName = layoutName.trim();
		}
		return layoutName;
	}
}
