package kr.xit.ens.kakao.talk.web;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.xit.biz.ens.model.kakao.talk.KkotalkApiDTO;
import kr.xit.biz.ens.model.kakao.talk.KkotalkDTO;
import kr.xit.core.model.ApiResponseDTO;
import kr.xit.core.model.IApiResponse;
import kr.xit.ens.kakao.talk.service.IKkotalkEltrcDocService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <pre>
 * description : 카카오톡 전자 문서 발송 controller
 * packageName : kr.xit.ens.kakao.talk.web
 * fileName    : KkotalkEltrcDocController
 * author      : julim
 * date        : 2024-08-12
 * ======================================================================
 * 변경일         변경자        변경 내용
 * ----------------------------------------------------------------------
 * 2024-08-12    julim       최초 생성
 *
 * </pre>
 */
@Tag(name = "KkotalkEltrcDocController", description = "카카오톡 전자문서 API")
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api/ens/kakao/v2")
public class KkotalkEltrcDocController {
    private final IKkotalkEltrcDocService service;

    /**
     * <pre>
     * 모바일웹 연계 문서발송 요청
     * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
     * </pre>
     * @param reqDTO KkopayDocDTO.SendRequest
     * @return ApiResponseDTO<KkopayDocDTO.SendResponse>
     */
    @Operation(summary = "문서발송 요청", description = "카카오톡 전자문서 서버로 문서발송 처리를 요청")
    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
        @Content(mediaType = "application/json", examples = {
            @ExampleObject(
                name = "D10",
                value = """
                {
                  "productCode": "D10_1",
                  "envelope": {
                    "title": "전자문서",
                    "content": {
                        "link": "https://nps.or.kr"
                    },
                    "guide": "국민연금 공단에서 보내는 문서입니다.",
                    "payload": "이용기관 페이로드",
                    "readExpiresAt": "2023-12-31T10:00:00",
                    "reviewExpiresAt": "2023-12-31T13:00:00",
                    "useNonPersonalizedNotification": true,
                    "phoneNumber": "01099999999",
                    "name": "홍길동",
                    "birthday": "20000303",
                    "externalId": "external_id1"
                  },
                  "signguCode": "51110",
                  "ffnlgCode": "11"
                }
            """),
            @ExampleObject(
                name = "D11",
                value = """
                {
                  "productCode": "D11_1",
                  "envelope": {
                    "title": "전자문서",
                    "content": {
                        "html": "<!DOCTYPEhtml><html><body><h1>MyFirstHeading</h1><p>Myfirstparagraph.</p></body></html>"
                    },
                    "guide": "국민연금 공단에서 보내는 문서입니다.",
                    "readExpiresAt": "2023-12-31T10:00:00",
                    "reviewExpiresAt": "2023-12-31T13:00:00",
                    "ci": "${CI}"
                  },
                  "signguCode": "51110",
                  "ffnlgCode": "11"
                }
            """)
        })
    })
    @PostMapping(value = "/envelopes", produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse requestSend(
        @RequestBody final KkotalkDTO.SendRequest reqDTO
    ) {
        return ApiResponseDTO.success(service.requestSend(reqDTO));
    }

    /**
     * <pre>
     * 토큰 유효성 검증(Redirect URL  접속 허용/불허)
     * </pre>
     * @param reqDTO KkopayDocDTO.ValidTokenRequest
     * @return ApiResponseDTO<KkopayDocDTO.ValidTokenResponse>
     */
    @Operation(summary = "토큰 유효성 검증", description = "Redirect URL 접속 허용/불허")
    @PostMapping(value = "/validToken", produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse validToken(
        @RequestBody final KkotalkDTO.ValidTokenRequest reqDTO
    ) {
        return ApiResponseDTO.success(service.validToken(reqDTO));
    }

    /**
     * <pre>
     * 문서 열람처리 API
     * -.문서에 대해서 열람 상태로 변경. 사용자가 문서열람 시(OTT 검증 완료 후 페이지 로딩 완료 시점) 반드시 문서 열람 상태 변경 API를 호출해야 함.
     * -.미 호출 시 아래와 같은 문제 발생
     * 1)유통증명시스템을 사용하는 경우 해당 API를 호출한 시점으로 열람정보가 등록되어 미 호출 시 열람정보가 등록 되지 않음.
     * 2)문서상태조회 API(/v1/envelopes/${ENVELOPE_ID}/read) 호출 시 read_at최초 열람시간) 데이터가 내려가지 않음.
     * </pre>
     * @param reqDTO KkotalkApiDTO.EnvelopeStatusResponse
     * @return ApiResponseDTO<Void>
     */
    @Operation(summary = "문서열람처리(문서 상태 변경)", description = "문서열람처리(문서 상태 변경)")
    @PostMapping(value = "/modifyStatus", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse modifyStatus(
        @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO
    ) {
        service.modifyStatus(reqDTO);
        return ApiResponseDTO.empty();
    }

    /**
     * <pre>
     * 문서 상태 조회 API
     * -.이용기관 서버에서 카카오페이 전자문서 서버로 문서 상태에 대한 조회를 요청 합니다.
     * : 발송된 문서의 진행상태를 알고 싶은 경우, flow와 상관없이 요청 가능
     * : polling 방식으로 호출할 경우, 호출 간격은 5초를 권장.
     * -.doc_box_status 상태변경순서
     * : SENT(송신) > RECEIVED(수신) > READ(열람)/EXPIRED(미열람자료의 기한만료)
     * </pre>
     * @param reqDTO KkotalkDTO.EnvelopeId
     * @return ApiResponseDTO<KkotalkApiDTO.EnvelopeStatusResponse>
     */
    @Operation(summary = "문서 상태 조회", description = "문서 상태 조회")
    @PostMapping(value = "/findStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse findStatus(
        @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO
    ) {
        return ApiResponseDTO.success(service.findStatus(reqDTO));
    }

    @Operation(summary = "대량 문서발송 요청 -> batch sendBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서발송 처리를 요청 -> batch sendBulks 에서 호출")
    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
        @Content(mediaType = "application/json", examples = {
            @ExampleObject(
                name = "D10",
                value = """
                {
                  "productCode": "D10_1",
                  "signguCode": "51110",
                  "ffnlgCode": "11",
                  "envelopes": [
                       {
                           "title": "전자문서",
                           "content": {
                               "html": "<!DOCTYPEhtml><html><body><h1>MyFirstHeading</h1><p>Myfirstparagraph.</p></body></html>"
                           },
                           "guide": "국민연금 공단에서 보내는 문서입니다.",
                           "readExpiresAt": "2024-12-31T10:00:00",
                           "reviewExpiresAt": "2025-03-31T13:00:00",
                           "phoneNumber": "01099999999",
                           "name": "홍길동",
                           "birthday": "20000303",
                           "externalId": "external_id1"
                       },
                       {
                           "title": "전자문서",
                           "content": {
                               "html": "<!DOCTYPEhtml><html><body><h1>MyFirstHeading</h1><p>Myfirstparagraph.</p></body></html>"
                           },
                           "guide": "국민연금 공단에서 보내는 문서입니다.",
                           "readExpiresAt": "2024-12-31T10:00:00",
                           "reviewExpiresAt": "2025-03-31T13:00:00",
                           "hash": "b0c34fdc5e2ecb0335919fdad3b2ada28fa3ab90ec16e9055c3e9e05c431c6e8",
                           "ci": "vMtqVxJX56lBgbf9heK3QTc+jVndTfK77i/UJKAzPmBG4n9CazCdd/8YytlFZnN4qofIqgxHpSoiG0yYzgEpJg==",
                           "externalId": "external_id2"
                       }
                    ]
                }
            """),
            @ExampleObject(
                name = "D11",
                value = """
                {
                  "productCode": "D11_1",
                  "signguCode": "51110",
                  "ffnlgCode": "11",
                  "envelopes": [
                       {
                           "title": "전자문서",
                           "content": {
                               "link": "https://nps.or.kr"
                           },
                           "guide": "국민연금 공단에서 보내는 문서입니다.",
                           "payload": "이용기관 페이로드",
                           "readExpiresAt": "2024-12-31T10:00:00",
                           "reviewExpiresAt": "2025-03-31T13:00:00",
                           "phoneNumber": "01099999999",
                           "name": "홍길동",
                           "birthday": "20000303",
                           "externalId": "external_id1"
                       },
                       {
                           "title": "전자문서",
                           "content": {
                               "link": "https://nps.or.kr"
                           },
                           "guide": "국민연금 공단에서 보내는 문서입니다.",
                           "payload": "이용기관 페이로드",
                           "readExpiresAt": "2024-12-31T10:00:00",
                           "reviewExpiresAt": "2025-03-31T13:00:00",
                           "ci": "${CI}",
                           "externalId": "external_id2"
                       }
                   ]
                }
            """)
        })
    })
    @PostMapping(value = "/envelopes/bulk", produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse requestSendBulk(
        @RequestBody final KkotalkDTO.BulkSendRequest reqDTO
    ) {
        return ApiResponseDTO.success(service.requestSendBulk(reqDTO));
    }

    /**
     * <pre>
     * 모바일웹 연계 문서발송 요청
     * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
     * </pre>
     * @param reqDTO KkotalkApiDTO.BulkStatusRequest
     * @return KkotalkApiDTO.BulkStatusResponse
     */
    @Operation(summary = "대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출")
    @PostMapping(value = "/envelopes/bulk/status", produces = MediaType.APPLICATION_JSON_VALUE)
    public IApiResponse findBulkStatus(
        @RequestBody final KkotalkDTO.BulkStatusRequest reqDTO
    ) {
        return ApiResponseDTO.success(service.findBulkStatus(reqDTO));
    }
}
