package com.eactive.eai.custom.message;

import org.apache.commons.lang3.StringUtils;

import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;

/**
 * DJBank(제주은행) 차세대 표준전문 InterfaceMapper
 *
 * HEAD 영역이 평면 구조로 변경됨에 따라 필드 접근 경로 및 값 변환 로직을 재정의.
 *
 * 주요 변경사항:
 *  - GUID: 40자 (기존 36자)
 *  - GUID 진행번호: HEAD.guid_prgs_no 별도 필드 (기존 GUID 문자열 내 포함)
 *  - 처리결과구분코드: S(성공)/F(오류) (기존 NR/ER)
 *  - 시스템환경구분코드: D/T/P (기존 O/S/D)
 */
@SuppressWarnings("serial")
public class InterfaceMapperDJB extends DefaultInterfaceMapper {

    private static final String PATH_MCI_NODE  = "HEAD.mci_node_dvcd";
    private static final String PATH_EAI_NODE  = "HEAD.eai_node_dvcd";
    private static final String PATH_MCI_SESN  = "HEAD.mci_sesn_id";

    // 처리결과구분코드 DJBank 값
    private static final String PROCS_RSLT_SUCCESS = "S";
    private static final String PROCS_RSLT_FAIL    = "F";
    
	private static String API_ID_PREFIX = StringUtils
			.defaultString(PropManager.getInstance().getProperty("API_ID_PREFIX"));

    @Override
    public String getEaiSvcCode(StandardMessage standardMessage) {
    	if(StringUtils.isNotBlank(standardMessage.getEaiSvcCd()))
    		return standardMessage.getEaiSvcCd();
    	
        String eaiInterfaceId    = getInterfaceId(standardMessage);
//    	String txId = getServiceId(standardMessage);
        String sendRecvDvcd   = getSendRecvDivision(standardMessage); // S | R
        String inExDivision   = getInExDivision(standardMessage);     // 1 | 2
        
        if(StringUtils.isEmpty(eaiInterfaceId))
        	throw new RuntimeException("not found if_id");
        
        return API_ID_PREFIX + StringUtils.substring(eaiInterfaceId, 2) + sendRecvDvcd + StringUtils.defaultString(inExDivision);
    }

    // ----------------------------------------------------------------
    // GUID (40자 고정)
    // ----------------------------------------------------------------

    @Override
    public void setGuid(StandardMessage standardMessage, String guid) {
        if (guid == null) throw new RuntimeException("guid is null");
        if (guid.length() != GUIDGeneratorDJB.GUID_LENGTH) {
            throw new RuntimeException("GUID length must be " + GUIDGeneratorDJB.GUID_LENGTH + ", actual=" + guid.length());
        }
        setItemValue(standardMessage, getPath(GUID), guid);
    }

    @Override
    public String getGuid(StandardMessage standardMessage) {
        return StringUtils.defaultString(getItemValue(standardMessage, getPath(GUID)));
    }

    // ----------------------------------------------------------------
    // GUID 진행번호 — HEAD.guid_prgs_no 별도 필드
    // ----------------------------------------------------------------

    @Override
    public String getGuidSeq(StandardMessage standardMessage) {
        String val = getItemValue(standardMessage, getPath(GUID_SEQ));
        if (StringUtils.isBlank(val)) return "001";
        try {
            // NUMBER 타입은 내부적으로 선행 0 제거 → 조회 시 3자리로 복원
            return String.format("%03d", Integer.parseInt(val.trim()));
        } catch (NumberFormatException e) {
            return StringUtils.defaultString(val, "001");
        }
    }

    @Override
    public void setGuidSeq(StandardMessage standardMessage, String guidSeq) {
        setItemValue(standardMessage, getPath(GUID_SEQ), guidSeq);
    }

    @Override
    public String nextGuidSeq(StandardMessage standardMessage) {
        String current = getGuidSeq(standardMessage);
        int seq = 1;
        try {
            seq = Integer.parseInt(current.trim()) + 1;
        } catch (NumberFormatException e) {
            seq = 2;
        }
        String next = String.format("%03d", seq);
        setGuidSeq(standardMessage, next);
        return next;
    }

    // ----------------------------------------------------------------
    // 원거래 GUID — HEAD.ortr_guid (40자 그대로)
    // ----------------------------------------------------------------

    @Override
    public String getOrgGuid(StandardMessage standardMessage) {
        return StringUtils.defaultString(getItemValue(standardMessage, getPath(GUID_ORG)));
    }

    @Override
    public void setOrgGuid(StandardMessage standardMessage, String orgGuid) {
        setItemValue(standardMessage, getPath(GUID_ORG), orgGuid);
    }

    // ----------------------------------------------------------------
    // 처리결과구분코드: 엔진 내부(0=정상, 1=오류) ↔ DJBank(S/F)
    // ----------------------------------------------------------------

    @Override
    public String getResponseType(StandardMessage standardMessage) {
        String val = getItemValue(standardMessage, getPath(RESPONSE_TYPE));
        if (PROCS_RSLT_SUCCESS.equals(val)) return STDMessageKeys.RESPONSE_TYPE_CODE_N;
        if (PROCS_RSLT_FAIL.equals(val))    return STDMessageKeys.RESPONSE_TYPE_CODE_E;
        return val;
    }

    @Override
    public void setResponseType(StandardMessage standardMessage, String responseType) {
        String siteVal;
        if (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)) {
            siteVal = PROCS_RSLT_SUCCESS;
        } else if (STDMessageKeys.RESPONSE_TYPE_CODE_E.equals(responseType)) {
            siteVal = PROCS_RSLT_FAIL;
        } else {
            siteVal = responseType;
        }
        setItemValue(standardMessage, getPath(RESPONSE_TYPE), siteVal);
    }

    // ----------------------------------------------------------------
    // 원거래복원여부: Y/N 그대로 사용 (엔진 내부 1/0과 변환)
    // ----------------------------------------------------------------

    @Override
    public String getRecoverYn(StandardMessage standardMessage) {
        String val = getItemValue(standardMessage, getPath(RECOVER_YN));
        return "Y".equals(val) ? "1" : "0";
    }

    @Override
    public void setRecoverYn(StandardMessage standardMessage, String recoverYn) {
        setItemValue(standardMessage, getPath(RECOVER_YN), "1".equals(recoverYn) ? "Y" : "N");
    }

    // ----------------------------------------------------------------
    // 인터페이스ID (trim 처리)
    // ----------------------------------------------------------------

    @Override
    public String getInterfaceId(StandardMessage standardMessage) {
        String val = getItemValue(standardMessage, getPath(INTERFACE_ID));
        return val == null ? "" : val.trim();
    }

    // ----------------------------------------------------------------
    // 세션ID / 인스턴스코드 — MCI 여부에 따라 처리
    // ----------------------------------------------------------------

    @Override
    public String getSessionId(StandardMessage standardMessage) {
        EAIServerManager server = EAIServerManager.getInstance();
        if (server != null && server.isMCI()) {
            return StringUtils.defaultString(getItemValue(standardMessage, PATH_MCI_SESN));
        }
        return "";
    }

    @Override
    public void setSessionId(StandardMessage standardMessage, String sessionId) {
        EAIServerManager server = EAIServerManager.getInstance();
        if (server != null && server.isMCI()) {
            setItemValue(standardMessage, PATH_MCI_SESN, sessionId);
        }
    }

    @Override
    public String getInstCode(StandardMessage standardMessage) {
        EAIServerManager server = EAIServerManager.getInstance();
        if (server != null && server.isMCI()) {
            return StringUtils.defaultString(getItemValue(standardMessage, PATH_MCI_NODE));
        }
        return StringUtils.defaultString(getItemValue(standardMessage, PATH_EAI_NODE));
    }

    @Override
    public void setInstCode(StandardMessage standardMessage, String instCode) {
        EAIServerManager server = EAIServerManager.getInstance();
        if (server != null && server.isMCI()) {
            setItemValue(standardMessage, PATH_MCI_NODE, instCode);
        } else {
            setItemValue(standardMessage, PATH_EAI_NODE, instCode);
        }
    }

    // ----------------------------------------------------------------
    // 요청시스템코드 — 채널유형코드(chnl_tycd)에서 추출
    // ----------------------------------------------------------------

    @Override
    public String getReqSysCode(StandardMessage standardMessage) {
        String chnlTycd = getItemValue(standardMessage, getPath(CHANNEL_TYPE_CD));
        if (StringUtils.isNotBlank(chnlTycd)) {
            return chnlTycd.trim();
        }
        // fallback: tx_id(서비스ID) 경로에서 추출
        String txId = getItemValue(standardMessage, getPath(SERVICE_ID));
        if (txId != null) {
            String[] split = txId.split("/");
            if (split.length > 1) {
                String route = split[1].toUpperCase();
                return route.length() > 3 ? route.substring(0, 3) : route;
            }
        }
        return null;
    }
}
