package kr.xit.biz.ens.model.ktgbs;

import java.util.List;

import javax.validation.Valid;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import io.swagger.v3.oas.annotations.media.Schema;
import kr.xit.biz.ens.model.cmm.CmmEnsRequestDTO;
import kr.xit.biz.ens.model.kt.KtCommonDTO;
import kr.xit.core.model.IApiResponse;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

/**
 * <pre>
 * description : 
 * packageName : kr.xit.biz.ens.model.ktgbs
 * fileName    : KtGbsApiDTO
 * author      : limju
 * date        : 2024-08-19
 * ======================================================================
 * 변경일         변경자        변경 내용
 * ----------------------------------------------------------------------
 * 2024-08-19   limju       최초 생성
 *
 * </pre>
 */
public class KtGbsDTO {

    //-------------------------------------------------------------------
    // 메세지 발송
    //-------------------------------------------------------------------
    @Schema(name = "MsgSendRequest DTO", description = "메세지 발송 요청 request DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @EqualsAndHashCode(callSuper = false)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class MsgSendRequest extends KtCommonDTO.KtMnsRequest {
        /**
         * 기관코드 - 필수(5자리)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "기관코드", example = "51110")
        @Size(min = 5, max = 5, message = "기관코드는 필수 입니다(5자리)")
        private String serviceCd;

        /**
         * 문서코드 - 필수(5자리)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "문서코드", example = "DP112")
        @Size(min = 5, max = 5, message = "기관코드는 필수 입니다(5자리)")
        private String msgCd;

        /**
         * 생성일시 - 필수(14자리) : yyyymmddHHmiss
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "생성일시", example = "20240819123456")
        @Size(min = 5, max = 5, message = "생성일시는 필수 입니다(14자리)")
        private String makeDt;

        /**
         * 회차전체데이터건수 - 필수(max:8자리)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "회차전체데이터건수", example = " ")
        @Digits(integer = 8, fraction = 0, message = "회차전체데이터건수(max:8자리)")
        private Integer dataCnt;

        /**
         * 발송마감시간 - 필수(yyyyMMddHHmiss : 14자리)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "발송마감시간(yyyyMMddHHmiss)", example = " ")
        @Size(min = 14, max = 14, message = "발송마감시간(yyyyMMddHHmiss)")
        private String sndnExTime;

        /**
         * 열람마감시간 - 필수(yyyyMMddHHmiss : 14자리)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "열람마감시간(yyyyMMddHHmiss)", example = " ")
        @Size(min = 14, max = 14, message = "열람마감시간(yyyyMMddHHmiss)")
        private String exTime;

        /**
         * 문서종류 - 필수(3자리 : sms|lms|mms)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "문서종류(sms|lms|mms)", example = "mms", allowableValues = {
            "sms", "lms", "mms"})
        @Size(min = 1, max = 3, message = "문서종류(sms|lms|mms)")
        @JsonProperty("m_type")
        private String mType;

        /**
         * 발송메세지타입 - 필수(1자리 : 1-RCS, 2-xMS)
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "발송메세지타입(1-RCS, 2-xMS)", example = " ", allowableValues = {
            "1", "2"})
        @Size(min = 1, max = 1, message = "발송메세지타입(1-RCS, 2-xMS)")
        private String msgType;

        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        @Valid
        private List<MsgSendReqsData> reqs;

        /**
         * 발신번호(서비스기관발송전화번호)
         */
        @Schema(title = "발신번호", example = " ")
        @Size(max = 20, message = "발신번호(max:20)")
        private String sndTelNo;

        /**
         * 메세지발송구분
         */
        @Schema(title = "메세지발송구분", example = " ")
        @Digits(integer = 8, fraction = 0, message = "메세지발송구분(max:1자리)")
        private Integer optType;
    }


    @Schema(name = "MsgSendReqsData", description = "메세지 발송 요청 reqs DTO")
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class MsgSendReqsData {
        //-------------------------------------------------------------------
        // 필수
        //-------------------------------------------------------------------
        /**
         * 관리키 : 고객메시지 건별 Unique key
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "관리키", example = "S20211229102000011")
        @NotEmpty(message = "관리키는 필수 입니다(max:50)")
        @Size(max = 50)
        private String srcKey;

        /**
         * 리스트순번 : max 8자리
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "리스트순번", example = "1")
        @NotEmpty(message = "리스트 순번은 필수 입니다(max:8)")
        @Size(max = 8)
        private String srcSeq;

        /**
         * 개인식별코드 : 88 자리
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "개인식별코드", example = "vMtqVxJX56lBgbf9heK3QTc+jVndTfK77i/UJKAzPmBG4n9CazCdd/8YytlFZnN4qofIqgxHpSoiG0yYzgEpJg==")
        @Size(min = 88, max = 88, message = "개인식별코드는 필수 입니다(88자리)")
        private String sci;

        /**
         * <pre>
         * MMS 상세내용 : max 4000
         * URL 없음
         * {#INFO_CFRM_STR}, {#RCVE_RF_STR} 문자열이 없는 경우 요청 거부 처리 함.
         * 단, 유통정보미생성여부가 'Y'인 경우 {#RCVE_RF_STR} 문자열만 체크.
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "MMS 상세내용", example = "{#INFO_CFRM_STR}, {#RCVE_RF_STR}")
        @Size(min = 1, max = 4000, message = "MMS 상세내용 필수입니다(max:4000)")
        private String mmsDtlCnts;

        /**
         * <pre>
         * MMS 제목 : max 40
         * utf-8 한글20자
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "MMS 제목(max:40)", example = "공유재산사용료 정기분")
        @Size(min = 1, max = 40, message = "MMS 제목은 필수 입니다(max:40)")
        private String mmsTitle;
       //-------------------------------------------------------------------

        /**
         * <pre>
         * RCS 메세지 상세내용 : max 4000 - RCS|Binary 전송시 필수
         * RCS 메시지 fallback 시 mms_dtl_cnts를 사용하며
         * RCS title은 mms_title 항목을 함께 사용한다.
         * </pre>
         */
        @Schema(title = "RCS 메세지 상세내용(max:4000)", example = " ")
        @Size(max = 4000, message = "RCS 메세지 상세내용은 4000자를 넘을 수 없습니다.")
        private String rcsDtlCnts;


        /**
         * <pre>
         * 연결 URL
         * </pre>
         */
        @Schema(title = "연결 URL", example = "http://localhost:18090/api/biz/kt/v1/cfmToken")
        private String url;

        /**
         * 문서해시 : max 64
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "문서해시(max:64)", example = "gdlIa53FZGQz5aKa3wLk33nW57N3mDpcwHytWlWMhzxHKulk7EZs143442394326642342364238648423864237")
        @Size(max = 64, message = "문서해시 64자를 넘을 수 없습니다.")
        private String docHash;

        /**
         * <pre>
         * 개인휴대전화번호 : 11 자리
         * 특정 MDN으로 발송할 경우
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.AUTO, title = "개인휴대전화번호(max:11)", example = "01093414345")
        @Size(max = 11, message = "개인 휴대 전화번호는 11자리 입니다")
        private String mdn;
    }
    //-------------------------------------------------------------------
    // 메세지 발송
    //-------------------------------------------------------------------


    //-------------------------------------------------------------------
    // 메세지 발송 및 수신결과 전송
    //-------------------------------------------------------------------
    @Schema(name = "MsgRsltRequest", description = "메세지 발송 및 수신결과 전송 요청 DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @EqualsAndHashCode(callSuper = false)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class MsgRsltRequest {
        /**
         * <pre>
         * 기관코드 : 필수 - 5
         * BizCenter에서 발행한 기관의 서비스 코드
         * </pre>>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "서비스코드", example = " ")
        @Size(min = 5, max = 5, message = "서비스코드는 필수 입니다(5자리)")
        private String serviceCd;

        @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
        @Valid
        private List<MsgRsltReqsData> reqs;
    }

    @Schema(name = "MsgRsltReqsData", description = "메세지 발송 및 수신결과 전송 reqs DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @EqualsAndHashCode(callSuper = false)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class MsgRsltReqsData extends CmmEnsRequestDTO {
        //-------------------------------------------------------------------
        // 필수
        //-------------------------------------------------------------------
        /**
         * 관리키 : 고객메시지 건별 Unique key
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "관리키", example = "S20211229102000001")
        @Size(min = 1, max = 50, message = "관리키는 필수 입니다(max:50)")
        private String srcKey;

        /**
         * <pre>
         * MMS 발송결과 상태 순번 : 필수 - max 8
         * 1:수신(결과), 열람(결과):2
         * </pre>>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "MMS 발송결과 상태 순번", example = " ", allowableValues = {
            "1", "2"})
        @Digits(integer = 8, fraction = 0, message = "MMS 발송결과 상태 순번(1|2)")
        private Integer mmsSndgRsltSqno;

        /**
         * <pre>
         * 처리일자 : 필수 - 8
         * 이통사 처리일자
         * </pre>>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "처리일자", example = "20231210")
        @Size(min = 8, max = 8, message = "처리일자는 필수 입니다(YYYYMMDD)")
        private String prcsDt;

        /**
         * 문서코드 : 필수 - 5자리
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "문서코드", example = "00001")
        @Size(min = 5, max = 5, message = "문서코드는 필수 입니다(5자리)")
        private String mmsBsnsDvcd;

        /**
         * <pre>
         * 모바일사업자구분 : 필수 - 2자리
         * 발송 통신사 구분(01:KT, 02:SKT, 03:LGT)
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "모바일사업자구분", example = "01", allowableValues = {"01","02","03"})
        @Size(min = 2, max = 2, message = "모바일 사업자 구분은 필수 입니다(01|02|03)")
        private String mblBzowrDvcd;

        /**
         * <pre>
         * TODO::결과코드에 따른 메세지 처리 필요
         * 발송결과코드 : 필수 - 2자리
         * 40	MMS/RCS 발송	수신성공
         * 41	MMS발송	메시지 내용 스팸
         * 42	MMS발송	착신자 스팸
         * 43	MMS발송	레포트 수신 시간 만료(메시지전송후 24시간 레포트 못받는 경우 )
         * 47	MMS발송	비가입자, 결번, 서비스정지
         * 48	MMS발송	단말기 전원 꺼짐
         * 49	MMS발송	기타
         * 4A	MMS발송	UNKNOWN/단말기형식오류(스팸설정)
         * 4D	MMS발송	전송 실패(무선망), 단말기 일시정지
         * 4J	MMS발송	비가용폰 오류
         * 4N	MMS발송	수신거부
         * 4O	MMS발송	LMS발송오류(시간초과)
         * 4P	MMS발송	LMS발송오류(기타)
         * 4T	MMS발송	가입자미존재(미동의포함)
         * 4Q	MMS발송	수신대기
         * 4R	MMS발송	다회선 제외
         * 4V	MMS발송	수신등록 휴대폰번호 미존재
         * 4W	MMS발송	기동의 사전문자 제외
         * 50	수신확인	수신성공
         * 60	열람확인	열람확인 (MMS발송결과순번=2, 열람타임스탬프가 있는 경우)
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "발송결과코드", example = "40")
        @Size(min = 2, max = 2, message = "발송결과코드는 필수 입니다")
        private String mmsRsltDvcd;

        /**
         * <pre>
         * 발송타임스탬프 : 필수 - 14
         * YYYYMMDDHHMISS
         * </pre>>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "발송타임스탬프", example = "20241030121000")
        @Size(min = 14, max = 14, message = "발송타임스탬프는 필수 입니다(YYYYMMDDHHMISS)")
        private String mmsSndgTmst;

        /**
         * <pre>
         * 문발송 메시지 타입: 필수 - 1
         * RCS/xMS (RCS :1, xMS: 2)
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "발송 메시지 타입", example = "2", allowableValues = {"1",
            "2"})
        @Size(min = 1, max = 1, message = "발송 메시지 타입은 필수 입니다")
        private String msgType;
        //-------------------------------------------------------------------

        /**
         * <pre>
         * 실제발송번호(일부) : max 20
         * 고객휴대폰번호 일부 (****0323)
         * </pre>
         */
        @Schema(title = "실제발송번호(일부)", example = " ")
        @Size(max = 20, message = "실제발송번호(일부)는 20자를 넘을 수 없습니다.")
        private String rlMmsSndgTelno;

        /**
         * <pre>
         * 수신타임스탬프 : 14
         * 수신시(mms_sndg_rslt_sqno 코드값이 1인 경우) 필수
         * </pre>>
         */
        @Schema(title = "수신타임스탬프", example = " ")
        @Size(max = 14, message = "수신타임스탬프는 14자리 입니다")
        private String mmsRcvTmst;

        /**
         * <pre>
         * 열람타임스탬프 : 14
         * 열람시(mms_sndg_rslt_sqno 코드값이 2인 경우) 필수
         * </pre>>
         */
        @Schema(title = "열람타임스탬프", example = " ")
        @Size(max = 14, message = "열람타임스탬프는 14자리 입니다")
        private String mmsRdgTmst;

        /**
         * <pre>
         * 기동의발송여부: 1
         * Y: 기동의(발송 시점 전 수신동의 및 전자주소가 생성되어있는 고객)
         * N: 미동의(발송 시점까지 수신동의 및 전자주소가 생성되어있지 않은 고객)
         * </pre>
         */
        @Schema(title = "기동의발송여부", example = "2", allowableValues = {"Y", "N"})
        @Size(max = 1, message = "기동의발송여부는 1자리 입니다(Y|N)")
        private String prevApproveYn;

        /**
         * API 정의서에 없는 필드 : 업무 편의를 위해 추가
         */
        @Schema(requiredMode = Schema.RequiredMode.AUTO, title = "발송결과코드메세지", example = "MMS/RCS 발송 수신성공")
        @Size(max = 100, message = "발송결과코드메세지는 100자를 넘을 수 없습니다")
        private String mmsRsltDvcdMsg;

        /**
         * MENS 업무처리를 위한 추가 항목
         */
        @Schema(title = "발송구분코드", example = " ")
        private String sndngSeCode;
    }
    //-------------------------------------------------------------------
    // 메세지 발송/수신결과 전송
    //-------------------------------------------------------------------


    //-------------------------------------------------------------------
    // token
    //-------------------------------------------------------------------
    /**
     * <pre>
     * KT GIBIS Token 발행
     * Request : TokenRequest
     * Response : TokenResponse
     * </pre>
     */
    @Schema(name = "TokenRequest", description = "KT GIBIS 토큰발행 요청 DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class TokenRequest {
        /**
         * 과태료 코드
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "클라이언트 ID", example = " ")
        @NotEmpty(message = "클라이언트 ID는 필수 입니다")
        @Size(max = 500)
        private String clientId;

        /**
         * 클라이언트 secret
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "클라이언트 secret", example = " ")
        @NotEmpty(message = "클라이언트 secret는 필수 입니다")
        @Size(max = 500)
        private String clientSecret;
    }

    @Schema(name = "TokenResponse", description = "KT GIBIS 토큰발행 요청 결과 DTO")
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class TokenResponse implements IApiResponse {
        //-------------------------------------------------------------------
        // 토큰 발행 성공시 필수
        //-------------------------------------------------------------------
        /**
         * 접근토큰 : 성공시 필수
         */
        @Size(max = 1000)
        private String accessToken;

        /**
         * <pre>
         * 접근 토큰 유형 : 성공시 필수
         * bearer 고정
         * </pre>
         */
        @Size(max = 100)
        private String tokenType;

        /**
         * 접근 토큰 유효 기간(초) : 성공시 필수수
         */
        @Size(max = 100)
        private String expiresIn;

        /**
         * <pre>
         * 접근토큰 권한범위 : 성공시 필수
         * 또는, 실패시 scope에러인 경우 발생
         * </pre>
         */
        @Size(max = 100)
        private String scope;
        //-------------------------------------------------------------------

        //-------------------------------------------------------------------
        // 토큰 발행 실패시 필수
        //-------------------------------------------------------------------
        private String timestamp;

        /**
         * 에러코드: 실패시 필수
         */
        @Size(max = 100)
        private String status;

        /**
         * <pre>
         * 에러명
         * </pre>
         */
        @Size(max = 100)
        private String error;

        /**
         * 에러메세지
         */
        @Size(max = 1000)
        private String message;

        /**
         * 경로
         */
        @Size(max = 1000)
        private String path;
    }

    /**
     * <pre>
     * KT GIBIS Token 인증 확인 조회 : BC-AG-SN-008
     * Request : KtTokenConfirmRequest
     * Response : KtTokenConfirmResponse
     * </pre>
     */
    @Schema(name = "TokenConfirmRequest", description = "KT GIBIS 토큰 인증 확인 요청 DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    @EqualsAndHashCode(callSuper = false)
    public static class TokenConfirmRequest extends KtCommonDTO.KtMnsRequest {
        /**
         * <pre>
         * 기관코드 : 필수 - 5
         * BizCenter에서 발행한 기관의 서비스 코드
         * </pre>>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "기관코드", example = " ")
        @NotEmpty(message = "기관코드는 필수 입니다(max:5)")
        private String serviceCd;

        /**
         * <pre>
         * 관리키 : 필수 - max:50
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "관리키", example = " ")
        @Size(min = 1, max = 50, message = "관리키는 필수 입니다(max:50)")
        private String srcKey;

        /**
         * <pre>
         * 토큰 : 필수 - max 128
         * </pre>
         */
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "토큰", example = " ")
        @NotEmpty(message = "토큰은 필수 입니다")
        private String token;
    }

    @Schema(name = "TokenReadRequest", description = "KT GIBIS 열람확인 결과 전송 요청 DTO")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    @EqualsAndHashCode(callSuper = true)
    public static class TokenReadRequest extends KtCommonDTO.KtMnsRequest {
        /**
         * <pre>
         * 기관코드 : 필수 - 5
         * BizCenter에서 발행한 기관의 서비스 코드
         * </pre>>
         */
        private String serviceCd;

        /**
         * <pre>
         * 토큰 : 필수 - max 150
         * </pre>
         */
        private String accessToken;

        /**
         * <pre>
         * 열람일시 : 14자 필수
         * </pre>>
         */
        private String mmsRdgTmst;
    }
    //-------------------------------------------------------------------
    // token
    //-------------------------------------------------------------------

}
