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

import com.eactive.eai.common.EAITable;
import com.eactive.eai.common.logger.HttpAdapterExtraLogVo;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.data.entity.onl.adapter.AdapterGroup;
import com.eactive.eai.data.entity.onl.server.EAIServer;
import com.eactive.eai.rms.common.combo.ComboVo;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.logging.UserAccessLogger;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.adapter.AdapterGroupService;
import com.eactive.eai.rms.data.entity.onl.logger.EAILogDetailSearch;
import com.eactive.eai.rms.data.entity.onl.logger.EAILogSearch;
import com.eactive.eai.rms.data.entity.onl.server.EAIServerService;
import com.eactive.eai.transformer.message.ISO8583MessageFactory;
import com.eactive.eai.transformer.util.CommonLib;
import com.eactive.eai.transformer.util.IConv;
import com.eactive.eai.transformer.util.ISO8583DumpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.solab.iso8583.IsoMessage;
import org.apache.commons.io.HexDump;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.*;

@Controller
public class DbTrackingController {
	private static final Logger logger = Logger
							.getLogger(DbTrackingController.class);

	private final DbTrackingService service;
	private final MonitoringContext monitoringContext;
	private final AdapterGroupService adapterGroupService;
	private final EAIServerService eaiServerService;
	
	private RestTemplate restTemplate = new RestTemplate();
	private final ObjectMapper objectMapper = new ObjectMapper();

	@Autowired
	public DbTrackingController(DbTrackingService service,
							MonitoringContext monitoringContext,
							AdapterGroupService adapterGroupService,
							EAIServerService eaiServerService) {
		this.service = service;
		this.monitoringContext = monitoringContext;
		this.adapterGroupService = adapterGroupService;
		this.eaiServerService = eaiServerService;
	}

	@GetMapping(value = "/onl/transaction/tracking/trackingMan.view")
	public String viewList() {
		return "/onl/transaction/tracking/trackingMan";
	}

	@GetMapping(value = "/onl/transaction/tracking/trackingMan.view", params = "cmd=DETAIL")
	public String viewDetail() {
		return "/onl/transaction/tracking/trackingManDetail";
	}

	@GetMapping(value = "/onl/transaction/tracking/trackingMan.view", params = "cmd=DETAILPOPUP")
	public String viewDetailPopup() {
		return "/onl/transaction/tracking/trackingManDetailpopup";
	}

	@GetMapping(value = "/onl/transaction/tracking/trackingMan.view", params = "cmd=TRANSFORMPOPUP")
	public String viewTransformpopup() {
		return "/onl/transaction/tracking/trackingManTransformpopup";
	}

	@GetMapping(value = "/onl/transaction/tracking/trackingMan.view", params = "cmd=TRANSFORMPOPUP2")
	public String viewTransformpopup2() {
		return "/onl/transaction/tracking/trackingManTransformpopup2";
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<EAILogUI>> selectList(
							HttpServletRequest request, Pageable pageable,
							EAILogSearch eaiLogSearch) {
		UserAccessLogger.log(request, "거래로그DB", "L", "cmd=LIST");
		Page<EAILogUI> page = service.selectList(pageable, eaiLogSearch);
		return ResponseEntity.ok(new GridResponse<>(page));
	}
	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=COUNT")
	public ResponseEntity<Map<String, Long>> selectList(HttpServletRequest request, EAILogSearch eaiLogSearch) {

		UserAccessLogger.log(request, "거래로그DB", "L", "cmd=COUNT");
		Map<String, Long> transactionCounts = service.getTransactionCounts(eaiLogSearch);

		long  totalLogs = transactionCounts.values().stream().mapToInt(Long::intValue).sum();
		long displayedLogs = Math.min(totalLogs, 1000);

		Map<String, Long> result = new HashMap<>();
		result.put("totalLogs", totalLogs);
		result.put("displayedLogs", displayedLogs);
		return ResponseEntity.ok(result);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL")
	public ResponseEntity<EAILogUI> selectDetail(
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		EAILogUI map = service.selectDetail(eaiLogDetailSearch);

		processDetail(eaiLogDetailSearch, map);

		return ResponseEntity.ok(map);
	}

	private void processDetail(EAILogDetailSearch eaiLogDetailSearch,
							EAILogUI map) {
		processXmlData(map);
		processBizData(eaiLogDetailSearch, map);
		processInputMediaData(map);
		processMsgType(map);
	}

	// XML 데이터 처리
	private void processXmlData(EAILogUI map) {

		map.setXmlDataYn("N"); // xml button hide/show
		map.setOrgDataYn("N"); // detail button hide/show

		String xmlYn = monitoringContext.getStringProperty(
								MonitoringContext.RMS_DBTRACKING_XML_YN, "N");

		if ("Y".equals(xmlYn)) {
			String logProcessNo = map.getLogprcssserno();

			if (("ASYN".equals(map.getSvcmotivusedstcd()) && "ASYN"
									.equals(map.getPsvintfacdsticname())) &&
									("100".equals(logProcessNo) || "300".equals(
															logProcessNo))
									&& ("100".equals(logProcessNo))) {
				map.setOrgDataYn("Y");
			}

			map.setXmlDataYn("Y");
		}

	}

	// 업무 데이터 처리 - 그리드로 보기
	// TODO: 그리드 보기 처리 수정 필요
	private void processBizData(EAILogDetailSearch eaiLogDetailSearch,
							EAILogUI map) {
		map.setBizDataYn("N");

		// table이 선언은 되었으나 service.resultByMessage에도 필요하지 않음.
		// String date = map.getMsgdpstyms();
		// String table = CommonUtil.getLogTable(date, true);
		try {
			LogBizResultItem logBizResultItem = service.resultByMessageWithLogDetail(eaiLogDetailSearch, map, "GRID");
			String bizData = logBizResultItem.getResultString();
			String base64LogDetail = new String(Base64.getEncoder().encode(logBizResultItem.getBizLogObjectDetail().getBytes("utf-8")));
			map.setBizLogObjectDetail(base64LogDetail);
			
			List<BizGridItem> bizGridList = new ArrayList<>();

			if (bizData != null) {
				String[] strArr = bizData.split("\\^LINE\\^");

				for (int i = 0; i < strArr.length; i++) {
					BizGridItem tmp = new BizGridItem();
					String biz = strArr[i];
					String[] bizArr = biz.split("\\^FLD\\^");

					for (int k = 0; k < bizArr.length; k++) {
						tmp.setRownum(i + 1);
						tmp.setName(bizArr[0]);
						tmp.setDesc(bizArr[1]);
						tmp.setValue(bizArr[2]);
						tmp.setLen(bizArr[3]);
					}

					bizGridList.add(tmp);
				}

				map.setBizDataYn("Y");
			}

			map.setBizGridRows(bizGridList);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	// 입력 매체 데이터 처리
	// 입력매체부 팝업 TELGMDMNDDSTCD CHNLDSTCD 수동어댑터가 표준이면서
	// INPTMDIAPARTLLEN(입력매체부 길이가 0이상)
	private boolean determineIsMedia(EAILogUI map, String targetSyncAsync,
							int logSeq, String inptmdiapartllen) {

		Optional<AdapterGroup> targetAdapterInfo = adapterGroupService
								.findById(map.getPsvsysadptrbzwkgroupname());
		String outAdptrMsgPtrnCd = targetAdapterInfo
								.map(AdapterGroup::getAdptrmsgptrncd)
								.orElse("N");

		// 표준 어댑터이고 입력 매체 부분 길이가 0보다 큰 경우 로직 실행
		if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(outAdptrMsgPtrnCd)
								&& Integer.parseInt(inptmdiapartllen) > 0) {

			// 비동기 서비스 조건 체크
			if ("ASYN".equals(map.getSvcmotivusedstcd())
									&& "ASYN".equals(targetSyncAsync)) {
				return logSeq == 200 || logSeq == 400;
			} else { // 동기 서비스 조건 체크
				return logSeq == 200 || logSeq == 300;
			}

		}

		return false; // 기본적으로 false 반환
	}

	private void processInputMediaData(EAILogUI map) {
		map.setInputMediaDataYn("N");

		String inptmdiapartllen = "0";

		int logSeq = Integer.parseInt(map.getLogprcssserno());
		String targetSyncAsync = map.getPsvintfacdsticname();
		boolean isMedia = determineIsMedia(map, targetSyncAsync, logSeq,
								inptmdiapartllen);

		if (isMedia) {
			map.setInputMediaDataYn("Y");
		}

	}

	// 메시지 유형 처리
	private void processMsgType(EAILogUI map) {
		int logSeq = Integer.parseInt(map.getLogprcssserno());
		String msgType;

		if (logSeq == 100 || logSeq == 400) {
			String sourceAdapter = map.getGstatsysadptrbzwkgroupname();
			Optional<AdapterGroup> sourceAdapterInfo = adapterGroupService
									.findById(sourceAdapter);
			msgType = sourceAdapterInfo.map(AdapterGroup::getAdptrmsgdstcd)
									.orElse("");
		} else {
			msgType = adapterGroupService
									.findById((map.getPsvsysadptrbzwkgroupname()))
									.map(AdapterGroup::getAdptrmsgdstcd)
									.orElse("");
		}

		map.setMsgType(msgType);

		if (ISO8583MessageFactory.isISO8583Message(msgType)) {
			map.setIso8583DataYn("Y");
		}

	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.excel", params = "cmd=LIST_GRID_TO_EXCEL")
	public ModelAndView listGridToExcel(Pageable pageable,
							EAILogSearch eaiLogSearch) {
		HashMap<String, Object> resultMap = new HashMap<>();

		List<Map<String, Object>> datas = service
								.selectListToExcel(eaiLogSearch);
		resultMap.put("datas", datas);
		return new ModelAndView("excelView", resultMap);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.excel", params = "cmd=LIST_BIZGRID_TO_EXCEL")
	public ModelAndView listBizGridToExcel(
							@RequestParam Map<String, Object> paramMap) {
		HashMap<String, Object> resultMap = new HashMap<>();
		Gson gson = new Gson();
		String jsonStr = (String) paramMap.get("gridData");
		resultMap.put("datas", gson.fromJson(jsonStr, HashMap[].class));
		return new ModelAndView("excelView", resultMap);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=LIST_COMBO")
	public ResponseEntity<Map<String, List<ComboVo>>> selectCombo() {
		Map<String, List<ComboVo>> map = service.selectCombo();
		return ResponseEntity.ok(map);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=LIST_DETAIL_COMBO")
	public ResponseEntity<Map<String, List<ComboVo>>> selectDetailCombo() {

		Map<String, List<ComboVo>> map = service.selectDetailCombo();
		return ResponseEntity.ok(map);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_XML")
	public String showXML(HttpServletRequest request,
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		String errorMsg = "";

		// 조회테이블 지정
		String date = eaiLogDetailSearch.getMsgDpstYMS();
		String table = CommonUtil.getLogTable(date, true);

		if (table == null || "".equals(table)) {
			// 에러
			errorMsg = "Unable to specify log table name. => time=" + date;
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupXml.jsp";
		}

		// 상세화면에서 업무구분코드는 지정하지 않아도 된다.

		// 조회
		EAILogUI data = service.selectDetail(eaiLogDetailSearch);

		if (data == null) {
			errorMsg = "Data retrieval failed";
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupXml.jsp";
		}

		String xmlData = service.resultByMessage(eaiLogDetailSearch,
								data, "XML");
		logger.warn("xmlData = " + xmlData);
		if (!xmlData.isEmpty())
			request.setAttribute("param", xmlData);
		return "forward:/common/jsp/popupXml.jsp";
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_JSON")
	public String showJSON() {

		return "forward:/common/jsp/popupJson.jsp";
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_INPTMDIA")
	public ModelAndView showINPTMDIA(HttpServletRequest request,
							HttpServletResponse response,
							@RequestParam Map<String, Object> paramMap,
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		EAILogUI map = service.selectDetail(eaiLogDetailSearch);

		// String date = eaiLogDetailSearch.getMsgDpstYMS();
		// String table = CommonUtil.getLogTable(date, true);
		String mediaData = service.resultByMessage(eaiLogDetailSearch,
								map, "MEDIA");

		List<HashMap<String, Object>> mediaGridList = new ArrayList<>();

		if (mediaData != null) {
			String[] strArr = mediaData.split("\\^LINE\\^");

			for (int i = 0; i < strArr.length; i++) {
				HashMap<String, Object> tmp = new HashMap<>();
				String biz = strArr[i];
				String[] bizArr = biz.split("\\^FLD\\^");

				for (int k = 0; k < bizArr.length; k++) {
					tmp.put("rownum", i + 1);
					tmp.put("name", bizArr[0]);
					tmp.put("desc", bizArr[1]);
					tmp.put("value", bizArr[2]);
					tmp.put("len", bizArr[3]);
				}

				mediaGridList.add(tmp);
			}

		}

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("rows", mediaGridList);
		return new ModelAndView("jsonView", resultMap);
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_EBCDIC")
	public String showEbcdic(HttpServletRequest request,
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		String errorMsg = "";

		// 조회테이블 지정
		String date = eaiLogDetailSearch.getMsgDpstYMS();
		String table = CommonUtil.getLogTable(date, true);

		if (table == null || "".equals(table)) {
			// 에러
			errorMsg = "Unable to specify log table name. => time=" + date;
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupXml.jsp";
		}

		// 조회
		EAILogUI eaiLogUI = service.selectDetail(eaiLogDetailSearch);

		if (eaiLogUI == null) {
			errorMsg = "Data retrieval failed";
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupMessage.jsp";
		}

		String bizData = eaiLogUI.getBzwkdatactnt();
		String printData = "";

		byte[] orgBytes = bizData.getBytes();

		printData = IConv.ebcdicToASCIIWithSOSIEX(orgBytes);

		String[] dump = CommonLib.makeDumpFormat(orgBytes);

		StringBuilder sb = new StringBuilder();

		for (String s : dump) {
			sb.append(s).append("<br>");
		}

		String dumpData = sb.toString();

		if (!printData.isEmpty()) {
			request.setAttribute("bizData", printData);
			request.setAttribute("bizDataHexa", dumpData);
		}

		return "forward:/common/jsp/popupMessage.jsp";
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_ORG")
	public String showOrgMessage(HttpServletRequest request,
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		String errorMsg = "";
		// 상세화면에서 업무구분코드는 지정하지 않아도 된다.
		EAILogUI data = service.selectDetail(eaiLogDetailSearch);

		if (data == null) {
			errorMsg = "Data retrieval failed";
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupMessage.jsp";
		}

		String bizData = data.getBzwkdatactnt();
		request.setAttribute("bizData", bizData);

		return "forward:/common/jsp/popupOrgMessage.jsp";
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_HTTP_LOG")
	public ResponseEntity<HttpAdapterExtraLogVo> selectHttpAdapterExtraLog(
							@RequestParam String prcsDate,
							@RequestParam String guid,
							@RequestParam int serviceProcessNumber) {
		return ResponseEntity.ok(service.selectHttpAdapterExtraLog(
				prcsDate, guid, serviceProcessNumber));
	}

	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_8583")
	public String showIso8583(HttpServletRequest request,
							EAILogDetailSearch eaiLogDetailSearch)
							throws Exception {
		String errorMsg = "";

		// 조회테이블 지정
		String date = eaiLogDetailSearch.getMsgDpstYMS();
		String table = CommonUtil.getLogTable(date, true);

		if (table == null || "".equals(table)) {
			// 에러
			errorMsg = "Unable to specify log table name. => time=" + date;
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupXml.jsp";
		}

		// 상세화면에서 업무구분코드는 지정하지 않아도 된다.

		// 조회
		EAILogUI data = service.selectDetail(eaiLogDetailSearch);

		if (data == null) {
			errorMsg = "Data retrieval failed";
			request.setAttribute("param", errorMsg);
			return "forward:/common/jsp/popupMessage.jsp";
		}

		String bizData = data.getBzwkdatactnt();
		String adapterName = "";

		try {
			String logPrcssSerno = eaiLogDetailSearch.getLogPrcssSerno();

			if (StringUtils.equalsAny(logPrcssSerno, "200", "300")) {
				adapterName = data.getPsvsysadptrbzwkgroupname();
			} else {
				adapterName = data.getGstatsysadptrbzwkgroupname();
			}

			Optional<AdapterGroup> adapterInfo = adapterGroupService
									.findById(adapterName);
			String adapterMsgType = adapterInfo
									.map(AdapterGroup::getAdptrmsgdstcd)
									.orElse(EAITable.ISO8583_TYPE);

			if (ISO8583MessageFactory.isISO8583Message(adapterMsgType)) {
				byte[] bizDataBytes = bizData.getBytes();
				IsoMessage m = MessageUtil.parseIsoMessage(bizDataBytes,
										adapterMsgType);
				String dump = ISO8583DumpUtil.dumpIsoMessageForEms(m,
										adapterMsgType);
				String result = "[Hex Dump]\n" + dumpstr(bizDataBytes) + "\n";
				result += "[Parsed Iso8583 Message]\n" + dump;
				bizData = result;
			}

		} catch (Exception ex) {
			logger.error("Error generating ISO8583 message", ex);
		}

		request.setAttribute("bizData", bizData);

		return "forward:/common/jsp/popupOrgMessage.jsp";
	}

	public static String dumpstr(final byte[] data) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

		try {
			HexDump.dump(data, 0, byteArrayOutputStream, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return new String(byteArrayOutputStream.toByteArray());
	}
	
	@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_PRETTY_VIEW")
	public ResponseEntity<?> selectList(@RequestParam Map<String, Object> paramMap) {
		
		List<EAIServer> serverList = eaiServerService.selectEaiServerIpList();
		
		if (serverList == null || serverList.isEmpty()) {
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                    .body(Collections.singletonMap("error", "접속 가능한 서버 목록이 없습니다."));
        }
		
		SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
		factory.setConnectTimeout(2000);
        factory.setReadTimeout(5000);
        RestTemplate restTemplate = new RestTemplate(factory);
        
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("intrefaceId", paramMap.get("intrefaceId"));
        requestBody.put("logProcessNo", paramMap.get("logProcessNo"));
        requestBody.put("bizData", paramMap.get("bizData"));
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
        
        Map<String, Object> resultResponse = null;
        boolean isSuccess = false;
        String lastErrorMsg = "";
        
        for(EAIServer server : serverList) {
        	
        	String ip = server.getEaisevrip();
        	String port = server.getSevrlsnportname();
        	
        	if(ip == null || port == null) continue;
        	
        	String targetUrl = "http://" + ip + ":" + port + "/PrettyPrint";
        	
        	try {
				
        		ResponseEntity<Map> response = restTemplate.exchange(
        				targetUrl,
        				HttpMethod.POST,
        				entity,
        				Map.class
        		);
        		
        		if(response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                    resultResponse = response.getBody();
                    isSuccess = true;
                    break;
                }
        		
        		
        	} catch (ResourceAccessException e) {
                lastErrorMsg = "Network Error: " + e.getMessage();
                logger.debug("서버 접속 실패 : " + lastErrorMsg);
                continue; 

            } catch (HttpStatusCodeException e) {
                String errorBodyString = e.getResponseBodyAsString(); 
                logger.debug("서버 내부 에러 [" + targetUrl + "] : " + errorBodyString);

                try {
                    // 에러 문자열을 Map(JSON 객체)으로 변환 시도
                    Map<String, Object> errorMap = objectMapper.readValue(errorBodyString, Map.class);
                    return ResponseEntity.status(e.getStatusCode()).body(errorMap);
                } catch (Exception parseError) {
                    // 일반 텍스트를 보냈다면 수동으로 Map 생성
                    Map<String, Object> manualErrorMap = new HashMap<>();
                    manualErrorMap.put("error", true);
                    manualErrorMap.put("result", errorBodyString); 
                    return ResponseEntity.status(e.getStatusCode()).body(manualErrorMap);
                }
            }
        	
        }
        
        if (isSuccess && resultResponse != null) {
        	
            return ResponseEntity.ok(resultResponse);
        } else {
            // 모든 서버 실패
            Map<String, Object> errorMap = new HashMap<>();
            errorMap.put("error", true);
            errorMap.put("result", "서버 연결 실패");
//            errorMap.put("result", "서버 연결 실패 (Last Error: " + lastErrorMsg + ")");
            logger.debug("서버 POST 요청 에러 : " + lastErrorMsg);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMap);
        }
	}
}
