package kr.xit.biz.mbl.service;

import org.springframework.stereotype.*;

import kr.xit.biz.ens.model.kakao.pay.*;
import kr.xit.biz.ens.model.kakao.talk.*;
import kr.xit.biz.ens.model.kt.*;
import kr.xit.biz.ens.model.ktgbs.*;
import kr.xit.biz.mbl.mapper.*;
import kr.xit.biz.mbl.model.*;
import kr.xit.biz.mbl.model.MobilePageDTO.*;
import kr.xit.core.consts.*;
import kr.xit.core.exception.*;
import kr.xit.core.model.*;
import kr.xit.core.service.*;
import kr.xit.core.spring.annotation.*;
import kr.xit.core.support.utils.*;
import kr.xit.ens.kakao.pay.service.*;
import kr.xit.ens.kakao.talk.service.*;
import kr.xit.ens.kt.service.*;
import kr.xit.ens.ktgbs.service.*;
import lombok.*;
import lombok.extern.slf4j.*;

/**
 * <pre>
 * description : 전자문서 중개자 모바일 페이지 API Service
 *
 * packageName : kr.xit.biz.mbl.service
 * fileName    : MobilePageService
 * author      : limju
 * date        : 2023-08-31
 * ======================================================================
 * 변경일         변경자        변경 내용
 * ----------------------------------------------------------------------
 * 2023-08-31    limju       최초 생성
 *
 * </pre>
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class MobilePageService extends AbstractService implements IMobilePageService {
    private final IMobilePageMapper mapper;
    private final IKkopayEltrcDocService kkopayService;
    private final IKkotalkEltrcDocService kkotalkService;
    private final IKtBcService ktBcService;
    private final IKtGbsService ktGbsService;

    /**
     * <pre>
     * 카카오 내문서함 모바일 페이지 컨탠트 요청</h3>
     * - 대상 : 문서발송요청(bulks-배치처리)을 통해 document_binder_uuid를 발급 받은 데이타
     * - 모바일의 redirect url을 통해 들어온 요청 처리
     *   -> 서버에서 해당 문서에 매핑한 모바일 페이지 내용을 앱에 전달
     *   -> 카카오페이 > 내문서함 > 문서 클릭시 실행
     *
     * 처리 내용
     * 1. 토큰유효성 검증(redirect url 접속 허용/불허
     * 2. 문서상태 변경
     *
     * @param reqDTO KkopayDocDTO.OneTimeToken
     * </pre>
     */
    //@Override
    @TraceLogging
    public String findKkopayReadyAndMblPage(MobilePageDTO.KakaoValidTokenRequest reqDTO) {

        if (Checks.isEmpty(reqDTO.getToken()) || Checks.isEmpty(reqDTO.getDocument_binder_uuid()) || Checks.isEmpty(reqDTO.getExternal_document_uuid()))
            throw BizRuntimeException.create(String.valueOf(ErrorCode.BAD_REQUEST.getHttpStatus().value()), "카카오페이 정상 요청이 아닙니다. 재인증 후 시도하시기 바랍니다.");

        final MobilePageManage mobilePageManage = mapper.selectKkopayMobilePage(reqDTO);
        if(mobilePageManage == null)    throw BizRuntimeException.create("데이타 오류[카카오페이 내문서함 정보가 없습니다]");

        // FIXME: 테스트를 위해 임시로 주석처리
        final ApiResponseDTO<KkopayDocDTO.ValidTokenResponse> res = kkopayService.findKkopayReadyAndMblPage(
            KkopayDocDTO.OneTimeToken.builder()
                .document_binder_uuid(reqDTO.getDocument_binder_uuid())
                .external_document_uuid(reqDTO.getExternal_document_uuid())
                .token(reqDTO.getToken())
                .signguCode(mobilePageManage.getSignguCode())
                .ffnlgCode(mobilePageManage.getFfnlgCode())
                .build()
        );
        if(!res.isSuccess()){
            throw BizRuntimeException.create(res.getCode(), res.getMessage());
        }
        return mobilePageManage.getMobilePageCn();
    }

    /**
     * <pre>
     * 카카오 내문서함 모바일 페이지 컨탠트 요청</h3>
     * - 대상 : 문서발송요청(bulks-배치처리)을 통해 document_binder_uuid를 발급 받은 데이타
     * - 모바일의 redirect url을 통해 들어온 요청 처리
     *   -> 서버에서 해당 문서에 매핑한 모바일 페이지 내용을 앱에 전달
     *   -> 카카오페이 > 내문서함 > 문서 클릭시 실행
     *
     * 처리 내용
     * 1. 토큰유효성 검증(redirect url 접속 허용/불허
     * 2. 문서상태 변경
     *
     * @param reqDTO KkopayDocDTO.OneTimeToken
     * </pre>
     */
    @Override
    @TraceLogging
    public String findKkotalkReadyAndMblPage(MobilePageDTO.KakaoValidTokenRequest reqDTO) {

        if (Checks.isEmpty(reqDTO.getToken()) || Checks.isEmpty(reqDTO.getEnvelopeId()) || Checks.isEmpty(reqDTO.getExternalId()))
            throw BizRuntimeException.create(String.valueOf(ErrorCode.BAD_REQUEST.getHttpStatus().value()), "카카오톡 정상 요청이 아닙니다. 재인증 후 시도하시기 바랍니다.");

        final MobilePageManage mobilePageManage = mapper.selectKkotalkMobilePage(reqDTO);
        if(mobilePageManage == null)    throw BizRuntimeException.create("데이타 오류[카카오톡 인증 문서 정보가 없습니다]");

        // FIXME: 테스트를 위해 임시로 주석처리
        final ApiResponseDTO<KkotalkApiDTO.ValidTokenResponse> res = kkotalkService.findKkotalkReadyAndMblPage(
            KkotalkApiDTO.ValidTokenRequest.builder()
                .envelopeId(reqDTO.getEnvelopeId())
                .token(reqDTO.getToken())
                .signguCode(mobilePageManage.getSignguCode())
                .ffnlgCode(mobilePageManage.getFfnlgCode())
                .build()
        );
        if(!res.isSuccess()){
            throw BizRuntimeException.create(res.getCode(), res.getMessage());
        }
        return mobilePageManage.getMobilePageCn();
    }

    /**
     * <pre>
     * KT BC 모바일 페이지 요청 처리
     * - 본문자 수신 등록 요청(BC-AG-SN-002) API 호출시
     *   -> url(callback)에 등록하여 호출 되게 됨
     *   -> callback url ? token=... 형태로
     * 1. 토큰인증확인조회요청(BC-AG-SN-008) API call
     * 2. 토큰열람확인결과 전송(BC-AG-SN-009) API call
     *    -> srcKey 획득
     * 3. kt 모바일 데이타 조회
     *    -> return
     * @param reqDTO KtTokenConfirmRequest
     * @return
     * </pre>
     */
    @Override
    @TraceLogging
    public String findKtBcMblPage(final KtTokenDTO.KtTokenConfirmRequest reqDTO) {
        if (Checks.isEmpty(reqDTO.getAccessToken()))
            throw BizRuntimeException.create(String.valueOf(ErrorCode.BAD_REQUEST.getHttpStatus().value()), "KT BC 안심문자 정상 요청이 아닙니다. 재인증 후 시도하시기 바랍니다.");

        final String signguCode = reqDTO.getSignguCode();
        final String ffnlgCode = reqDTO.getFfnlgCode();
        final KtTokenDTO.KtTokenConfirmResponse cfmRes = ktBcService.cfmToken(reqDTO);

        if(cfmRes.getResultCd().equals("00")){
            KtCommonDTO.KtCommonResponse readRes = ktBcService.readToken(
                KtTokenDTO.KtTokenReadRequest.builder()
                    .signguCode(signguCode)
                    .ffnlgCode(ffnlgCode)
                    .accessToken(reqDTO.getAccessToken())
                    .build()
            );

            if(readRes.getResultCd().equals("00")){
                String srcKey = cfmRes.getSrcKey();
                final MobilePageManage mobilePageManage = mapper.selectKtBcMobilePage(srcKey);
                return mobilePageManage.getMobilePageCn();
            }
            throw BizRuntimeException.create(readRes.getResultCd(), readRes.toStringErrorMsg());
        }
        throw BizRuntimeException.create(cfmRes.getResultCd(), cfmRes.toStringErrorMsg());
    }

    /**
     * <pre>
     * KT GIBIS 모바일 페이지 요청 처리
     * - 본문자 수신 등록 요청 API 호출시
     *   -> url(callback)에 등록하여 호출 되게 됨
     *   -> callback url ? token=... 형태로
     * 1. 토큰인증확인조회요청 API call
     * 2. 토큰열람확인결과 전송 API call
     *    -> srcKey 획득
     * 3. kt BIBIS 모바일 데이타 조회
     *    -> return
     * @param reqDTO KtTokenConfirmRequest
     * @return
     * </pre>
     */
    @Override
    @TraceLogging
    public String findKtGbsMblPage(final KtGbsDTO.TokenConfirmRequest reqDTO) {
        if (Checks.isEmpty(reqDTO.getToken()))
            throw BizRuntimeException.create(String.valueOf(ErrorCode.BAD_REQUEST.getHttpStatus().value()), "KT GIBIS 안심문자 정상 요청이 아닙니다. 재인증 후 시도하시기 바랍니다.");

        final String signguCode = reqDTO.getSignguCode();
        final String ffnlgCode = reqDTO.getFfnlgCode();
        final KtCommonDTO.KtCommonResponse cfmRes = ktGbsService.cfmToken(reqDTO);

        if(cfmRes.getResultCd().equals("00")){
            KtCommonDTO.KtCommonResponse readRes = ktGbsService.readToken(
                KtGbsDTO.TokenReadRequest.builder()
                    .signguCode(signguCode)
                    .ffnlgCode(ffnlgCode)
                    .accessToken(reqDTO.getToken())
                    .mmsRdgTmst(DateUtils.getTodayAndNowTime("yyyyMMddHHmmss"))
                    .build()
            );

            if(readRes.getResultCd().equals("00")){
                String srcKey = reqDTO.getSrcKey();
                final MobilePageManage mobilePageManage = mapper.selectKtGbsMobilePage(srcKey);
                return mobilePageManage.getMobilePageCn();
            }
            throw BizRuntimeException.create(readRes.getResultCd(), readRes.toStringErrorMsg());
        }
        throw BizRuntimeException.create(cfmRes.getResultCd(), cfmRes.toStringErrorMsg());
    }
}
