package com.eactive.eai.rms.onl.common.service.ums;

import lombok.Getter;

import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

@Getter
public class StandardMessageTemplate {
    private final Map<String, FieldDefinition> standardHeaderTemplate;
    private final Map<String, FieldDefinition> umsHeaderTemplate;
    private final Map<String, Map<String, FieldDefinition>> messageTemplates;

    public StandardMessageTemplate() {
        this.standardHeaderTemplate = initializeStandardHeaderTemplate();
        this.umsHeaderTemplate = initializeUmsHeaderTemplate();
        this.messageTemplates = initializeMessageTemplates();
    }
    
    private Map<String, FieldDefinition> initializeStandardHeaderTemplate() {
        Map<String, FieldDefinition> header = new LinkedHashMap<>();
        LocalDateTime now = LocalDateTime.now();

        header.put("tlgrLen", new FieldDefinition(8, "00012092"));  // 전문 길이
        header.put("strd_tlgr_vrsn", new FieldDefinition(3, "106"));  // 표준전문 버전
        header.put("ecryApplctnYn", new FieldDefinition(1, ""));  // 암호화 적용여부
        header.put("tlgrWrtnDt", new FieldDefinition(14, ""));  // 전문작성 일시
        header.put("tlgrCrtnSysNm", new FieldDefinition(8, "APIA11A1"));  // 전문생성 시스템
        header.put("tlgrSrlNo", new FieldDefinition(8, "00000001"));  // 전문 일련번호
        header.put("tlgrPrgrsNo", new FieldDefinition(2, "01"));  // 전문 진행번호
        header.put("orgnlTx", new FieldDefinition(32, ""));  // 원거래 Global ID
        header.put("ttlUseYn", new FieldDefinition(1, "0"));  // TTL 사용 여부
        header.put("frstStartTm", new FieldDefinition(6, ""));  // 최초 시작시간
        header.put("mntcTm", new FieldDefinition(3, ""));  // 유지 시간
        header.put("msgTpDscd", new FieldDefinition(1, ""));  // 메시지 유형 구분코드
        header.put("scrnId", new FieldDefinition(12, "PBKMAN000100"));  // 화면 ID
        header.put("natCd", new FieldDefinition(2, "KR"));  // 국가 코드
        header.put("lngDscd", new FieldDefinition(2, "ko"));  // 언어 구분코드
        header.put("crctnCnclDscd", new FieldDefinition(1, "1"));  // 정정취소 구분코드
        header.put("bizOpngYn", new FieldDefinition(1, "1"));  // 업무개시 여부
        header.put("clsgPstBizYn", new FieldDefinition(1, "0"));  // 마감후거래 여부
        header.put("mciIntfId", new FieldDefinition(16, ""));  // MCI 인터페이스 ID
        header.put("rcvSrvcCd", new FieldDefinition(13, ""));  // 수신 서비스 코드
        header.put("rsltRcvSrvcCd", new FieldDefinition(13, ""));  // 결과 수신 서비스 코드
        header.put("eaiIntfId", new FieldDefinition(15, ""));  // EAI 인터페이스 ID
        header.put("syncDscd", new FieldDefinition(1, "S"));  // 동기 구분코드
        header.put("asyncAtrbtDscd", new FieldDefinition(1, ""));  // Async 속성 구분코드
        header.put("reqRspnsDscd", new FieldDefinition(1, "S"));  // 요청 응답 구분코드
        header.put("xaTxDscd", new FieldDefinition(1, "0"));  // XA거래 구분코드
        header.put("exctnModeDscd", new FieldDefinition(1, "T"));  // 실행모드 구분코드
        header.put("chnlDscd", new FieldDefinition(3, ""));  // 채널 구분코드
        header.put("ipAddr", new FieldDefinition(32, ""));  // IP 주소
        header.put("macAddr", new FieldDefinition(12, ""));  // MAC 주소
        header.put("mciNodNo", new FieldDefinition(1, ""));  // MCI 노드번호
        header.put("mciInstcNo", new FieldDefinition(1, ""));  // MCI 인스턴스번호
        header.put("mciSssidNo", new FieldDefinition(32, ""));  // MCI 세션ID 번호
        header.put("extrInstCd", new FieldDefinition(3, ""));  // 대외기관 코드
        header.put("extrBizDscd", new FieldDefinition(3, ""));  // 대외업무 구분코드
        header.put("extrBizDtlsDscd", new FieldDefinition(2, ""));  // 대외업무 세부구분코드
        header.put("jntntClsCd", new FieldDefinition(10, ""));  // 공동망 종별코드
        header.put("jntntTxDscd", new FieldDefinition(10, ""));  // 공동망 거래구분코드
        header.put("sysIntfId", new FieldDefinition(23, ""));  // 시스템인터페이스 식별자
        header.put("linkTlgrTraceNo", new FieldDefinition(20, ""));  // 연계전문 추적번호
        header.put("linkSnrcDscd", new FieldDefinition(1, ""));  // 연계 송신수신 구분코드
        header.put("custId", new FieldDefinition(15, ""));  // 고객 식별자
        header.put("filler1", new FieldDefinition(5, ""));  // Filler1
        header.put("custRprsnId", new FieldDefinition(15, ""));  // 고객관련인 식별자
        header.put("deptId", new FieldDefinition(14, "014000"));  // 부서 식별자
        header.put("staffId", new FieldDefinition(15, "SMBUSR01"));  // 스태프 식별자
        header.put("filler2", new FieldDefinition(5, ""));  // Filler2
        header.put("tlgrRspnsDttm", new FieldDefinition(14, ""));  // 전문응답 일시
        header.put("prcsRsltDscd", new FieldDefinition(1, ""));  // 처리결과 구분코드
        header.put("outpTlgrTpCd", new FieldDefinition(1, ""));  // 출력전문 유형코드
        header.put("tlgrCtntNo", new FieldDefinition(2, ""));  // 전문 연속번호
        header.put("filler", new FieldDefinition(92, ""));  // 전체 Filler

        return header;
    }
    private Map<String, FieldDefinition> initializeUmsHeaderTemplate() {
        Map<String, FieldDefinition> header = new LinkedHashMap<>();

        // 시작부
        header.put("STR_DV_CD", new FieldDefinition(1, "~"));          // 시작구분코드
        header.put("TMSG_LEN", new FieldDefinition(8, "00010000"));   // 전문길이
        header.put("CHAR_SET_CD", new FieldDefinition(1, "U"));       // 문자셋코드 - UTF-8 only
        header.put("UMS_MSG_DV_CD", new FieldDefinition(1, ""));      // 메시지 구분코드
        header.put("RQST_DV_CD", new FieldDefinition(1, "Y"));         // 요청구분코드
        header.put("TMSG_SNRE_DRCT_DV_CD", new FieldDefinition(1, "S")); // 요청시(S), 응답전문시(R)
        header.put("CRTN_DT", new FieldDefinition(8, ""));            // 전문생성일자
        header.put("CRTN_TM", new FieldDefinition(6, ""));            // 전문생성시각
        header.put("SVC_ID", new FieldDefinition(10, ""));            // 서비스아이디

        // UMS헤더
        header.put("RQST_TMSG_NO", new FieldDefinition(30, ""));      // 요청전문번호
        header.put("SYS_YN", new FieldDefinition(1, "S"));             // 시스템여부
        header.put("RECV_TMSG_NO", new FieldDefinition(20, ""));      // 수신전문번호
        header.put("MSG_USER_ID", new FieldDefinition(20, "SMBUSR01"));       // 메시지 발송자 ID
        header.put("BUSS_BR_NO", new FieldDefinition(10, ""));        // 영업점번호
        header.put("DEPT_DV_CD", new FieldDefinition(10, "1002"));        // 부서구분코드
        header.put("PROC_RSLT_DV_CD", new FieldDefinition(1, ""));    // 처리결과구분코드
        header.put("PROC_RSLT_CD", new FieldDefinition(5, "00000"));   // 처리결과코드
        header.put("PROC_RSLT_MSG", new FieldDefinition(60, ""));     // 처리결과메시지
        header.put("ACPN_DT", new FieldDefinition(8, ""));            // 접수일자
        header.put("ACPN_DRTM", new FieldDefinition(6, ""));          // 접수시각
        header.put("MSG_CLAS_CD", new FieldDefinition(1, "0"));        // 메시지분류코드
        header.put("BIZ_SYS_DV_CD", new FieldDefinition(10, "CHS"));     // 업무시스템구분코드
        header.put("SNDG_BIZ_DV_CD", new FieldDefinition(10, "API"));    // 발송업무구분코드
        header.put("TMSG_RSEV_CTT", new FieldDefinition(20, ""));    // 전문예비내용

        // 채널 헤더
        header.put("MSG_KIND_CD", new FieldDefinition(1, "A"));    // 메시지 종류 코드
        header.put("VALD_TRM_SEC_CNT", new FieldDefinition(6, "030000")); // 유효기간초수
        header.put("IMDT_PROC_DV_CD", new FieldDefinition(1, "1"));    // 즉시처리구분코드
        header.put("RSV_DT", new FieldDefinition(8, "00000000"));             // 예약일자
        header.put("RSV_TM", new FieldDefinition(6, "000000"));             // 예약시각
        header.put("SD_TCNT", new FieldDefinition(1, "1"));           // 시도횟수
        header.put("SNDG_PRVW_YN", new FieldDefinition(1, "0"));      // 발송미리보기여부

        return header;
    }


    private Map<String, FieldDefinition> initializeSmsTemplate() {
        Map<String, FieldDefinition> sms = new LinkedHashMap<>();

        // SMS 전용 데이터 필드
        sms.put("SNDR_MVBL_TEL_NO", new FieldDefinition(14, ""));     // 발송인이동전화번호
        sms.put("SMS_RPLY_NO", new FieldDefinition(14, ""));          // SMS회신번호
        sms.put("DATPT_LEN", new FieldDefinition(8, ""));             // 실 메시지 길이
        sms.put("SMS_MSG", new FieldDefinition(80, ""));              // SMS메시지
        sms.put("GRID_ROWCOUNT", new FieldDefinition(3, "001"));      // 자료건수

        // 수신자 정보
        sms.put("UMSKEY", new FieldDefinition(20, ""));               // 발송전문번호
        sms.put("CUST_ID", new FieldDefinition(15, ""));              // 고객ID
        sms.put("ACNM_NO", new FieldDefinition(13, ""));              // 실명번호
        sms.put("CRD_NO", new FieldDefinition(16, ""));               // 카드번호
        sms.put("ACCT_NO", new FieldDefinition(20, ""));              // 계좌번호
        sms.put("RCPN_MVBL_TEL_NO", new FieldDefinition(14, ""));     // 수신자이동전화번호

        // 채널접수 정보
        sms.put("CHNL_ACPN_RSLT_TYPE_CD", new FieldDefinition(1, "")); // 채널접수결과 유형코드
        sms.put("CHNL_ACPN_RSLT_CD", new FieldDefinition(5, "0000")); // 채널접수 코드
        sms.put("CHNL_ACPN_MSG", new FieldDefinition(60, ""));        // 채널접수 메시지
        sms.put("END_DV_CD", new FieldDefinition(1, "^"));             // 종료구분코드

        return sms;
    }

    private Map<String, FieldDefinition> initializeEmailTemplate() {
        Map<String, FieldDefinition> email = new LinkedHashMap<>();

        // EMAIL 전용 데이터 필드
        email.put("SNDR_NM", new FieldDefinition(50, ""));            // 발송인명
        email.put("SNDR_EMAIL_ADR", new FieldDefinition(100, ""));    // 발송메일주소
        email.put("RTPN_EMAIL_ADR", new FieldDefinition(100, ""));    // 회신메일주소
        email.put("EMAIL_TTL", new FieldDefinition(250, ""));         // 이메일제목
        email.put("APNX_FILE_NM", new FieldDefinition(200, ""));      // 첨부파일명
        email.put("DATPT_LEN", new FieldDefinition(8, ""));           // 데이터부길이
        email.put("EMAIL_CTT", new FieldDefinition(32000, ""));       // 이메일내용
        email.put("GRID_ROWCOUNT", new FieldDefinition(3, "001"));    // 자료건수

        // 수신자 정보
        email.put("SNDG_TMSG_NO", new FieldDefinition(20, ""));       // 발송전문번호
        email.put("RCPN_CUST_ID", new FieldDefinition(15, ""));       // 고객ID
        email.put("ACNM_NO", new FieldDefinition(13, ""));            // 실명번호
        email.put("CRD_NO", new FieldDefinition(16, ""));             // 카드번호
        email.put("ACCT_NO", new FieldDefinition(20, ""));            // 계좌번호
        email.put("RCV_CUST_NM", new FieldDefinition(50, ""));        // 수신인고객명
        email.put("RCV_EMAIL_ADR", new FieldDefinition(100, ""));     // 수신인메일주소

        // 보안메일 정보
        email.put("SCRT_EMAIL_CD", new FieldDefinition(1, ""));       // 보안이메일부호
        email.put("SCRT_EMAIL_KEY1", new FieldDefinition(20, ""));    // 보안메일Key1
        email.put("SCRT_EMAIL_KEY2", new FieldDefinition(20, ""));    // 보안메일Key2

        // 채널접수 정보
        email.put("CHNL_ACPN_RSLT_TYPE_CD", new FieldDefinition(1, "")); // 채널접수구분코드
        email.put("CHNL_ACPN_RSLT_CD", new FieldDefinition(5, "0000")); // 채널접수코드
        email.put("CHNL_ACPN_MSG", new FieldDefinition(60, ""));      // 채널접수메시지
        email.put("END_DV_CD", new FieldDefinition(1, "^"));           // 종료구분코드

        return email;
    }

    private Map<String, FieldDefinition> initializeKakaoTemplate() {
        Map<String, FieldDefinition> kakao = new LinkedHashMap<>();

        // KAKAO 전용 데이터 필드
        kakao.put("KKO_SND_NO", new FieldDefinition(14, "15221000")); // 카카오발신번호
        kakao.put("KKO_SENDER_KEY", new FieldDefinition(40, ""));     // 카카오발신프로필키
        kakao.put("KKO_TMPLT_ID", new FieldDefinition(30, ""));       // 카카오템플릿ID
        kakao.put("KKO_CTT", new FieldDefinition(3000, ""));          // KTALK 메시지
        kakao.put("KKO_ATTACHMENT", new FieldDefinition(4000, ""));    // 버튼정보
        kakao.put("KKO_TITLE", new FieldDefinition(150, ""));         // 강조표기(알림톡용)
        kakao.put("KKO_SUPPLEMENT", new FieldDefinition(4000, ""));    // 바로연결(알림톡용)
        kakao.put("KKO_AD_FLAG", new FieldDefinition(1, ""));         // 광고표기
        kakao.put("KKO_WIDE", new FieldDefinition(1, ""));            // 이미지여부
        kakao.put("KKO_MESSAGE_TYPE", new FieldDefinition(2, "AT"));   // 메시지타입
        kakao.put("KKO_SMS_SND_YN", new FieldDefinition(1, "Y"));     // 대체발송여부
        kakao.put("KKO_SMS_SND_TITLE", new FieldDefinition(60, ""));  // 대체발송LMS제목
        kakao.put("KKO_SMS_SND_MSG", new FieldDefinition(4000, ""));  // 대체발송시 메시지
        kakao.put("GRID_ROWCOUNT", new FieldDefinition(3, "001"));    // 자료건수
        // 수신자 정보
        kakao.put("UMSKEY", new FieldDefinition(20, ""));             // 발송전문번호
        kakao.put("CUST_ID", new FieldDefinition(15, ""));            // 고객ID
        kakao.put("ACNM_NO", new FieldDefinition(13, ""));            // 실명번호
        kakao.put("CRD_NO", new FieldDefinition(16, ""));             // 카드번호
        kakao.put("ACCT_NO", new FieldDefinition(20, ""));            // 계좌번호
        kakao.put("RCPN_MVBL_TEL_NO", new FieldDefinition(14, ""));   // 수신자휴대폰번호

        // 채널접수 정보
        kakao.put("CHNL_ACPN_RSLT_TYPE_CD", new FieldDefinition(1, "")); // 채널접수구분코드
        kakao.put("CHNL_ACPN_RSLT_CD", new FieldDefinition(5, "00000")); // 채널접수코드
        kakao.put("CHNL_ACPN_MSG", new FieldDefinition(60, ""));      // 채널접수메시지
        kakao.put("END_DV_CD", new FieldDefinition(1, "^"));         // 종료구분코드

        return kakao;
    }


    private Map<String, Map<String, FieldDefinition>> initializeMessageTemplates() {
        Map<String, Map<String, FieldDefinition>> templates = new LinkedHashMap<>();
        templates.put("SMS", initializeSmsTemplate());
        templates.put("EMAIL", initializeEmailTemplate());
        templates.put("KAKAO", initializeKakaoTemplate());
        return templates;
    }

    public Map<String, FieldDefinition> getCompleteTemplate(String messageType) {
        Map<String, FieldDefinition> template = new LinkedHashMap<>();
        // 1. 표준 헤더 추가
        template.putAll(standardHeaderTemplate);
        // 2. UMS 공통 헤더 추가
        template.putAll(umsHeaderTemplate);
        // 3. 메시지별 전용 부분 추가
        Map<String, FieldDefinition> specificTemplate = messageTemplates.get(messageType.toUpperCase());
        if (specificTemplate != null) {
            template.putAll(specificTemplate);
        }
        return template;
    }
}