package cokr.xit.ens.biz.iup.billpay.presentation;

import cokr.xit.ens.biz.iup.billpay.service.IupPayUseSysServiceFactory;
import cokr.xit.ens.core.exception.EnsException;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Map;

@Tag(name = "IupPayUseSysController")
@Slf4j
@RequiredArgsConstructor
@RestController
//public class IupPayUseSysController implements PayUseSysController<ResponseEntity, Map<String, Object>> {
public class IupPayUseSysController {

    private final IupPayUseSysServiceFactory factory;

    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
            @Content(mediaType = "application/json", examples = {
                    @ExampleObject(name = "kkopay(카카오페이)"
                            , summary = "kkopay(카카오페이)"
                            , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}")
            })
    })
    @Parameters({
            @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH),
    })
    @Operation(summary = "청구서링크생성 정보")
    @PostMapping(value = "/iup/bill/{paySe}/gnr/url", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity gnrUrl(@PathVariable String paySe, @RequestBody Map<String, Object> param) {

        if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe)))
            throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm());
        return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).gnrUrl(param), HttpStatus.OK);
    }


    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
            @Content(mediaType = "application/json", examples = {
                    @ExampleObject(name = "kkopay(카카오페이)"
                            , summary = "kkopay(카카오페이)"
                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"user_birth\":\"\",\"parameters\":{\"some_param\":\"\"}}}"),
                    @ExampleObject(name = "nvpay(네이버페이)"
                            , summary = "nvpay(네이버페이)"
                            , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}")
            })
    })
    @Parameters({
            @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH),
    })
    @Operation(summary = "납부(결제)정보")
    @PostMapping(value = "/iup/bill/{paySe}/pay/notice", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity payNotice(@PathVariable String paySe, @RequestBody Map<String, Object> param) {

        if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe)))
            throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm());
        return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payNotice(param), HttpStatus.OK);
    }

    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
            @Content(mediaType = "application/json", examples = {
                    @ExampleObject(name = "kkopay(카카오페이)"
                            , summary = "kkopay(카카오페이)"
                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"amount\":29000,\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"}}}"),
                    @ExampleObject(name = "nvpay(네이버페이)"
                            , summary = "nvpay(네이버페이)"
                            , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\",\"productName\":\"\",\"totalPayAmount\":1000,\"taxScopeAmount\":1000,\"taxExScopeAmount\":null}}")
            })
    })
    @Parameters({
            @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH),
    })
    @Operation(summary = "납부(결제)가능여부")
    @PostMapping(value = "/iup/bill/{paySe}/pay/able", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity payAble(@PathVariable String paySe, @RequestBody Map<String, Object> param) {
        if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe)))
            throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm());
        return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payAble(param), HttpStatus.OK);
    }

    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
            @Content(mediaType = "application/json", examples = {
                    @ExampleObject(name = "kkopay(카카오페이)"
                            , summary = "kkopay(카카오페이)"
                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"},\"pay_by\":\"MONEY\",\"pay_type\":\"P\",\"pay_detail1\":\"\",\"pay_detail2\":\"\",\"amount\":20000,\"pay_amount\":20000,\"pay_fee_type\":\"BEFORE\",\"pay_fee\":150,\"pay_fee_tax\":15,\"paid_at\":\"20190220161656\",\"pay_id\":2748877}}"),
                    @ExampleObject(name = "nvpay(네이버페이)"
                            , summary = "nvpay(네이버페이)"
                            , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"paymentId\":\"네이버페이 결제번호\",\"detail\":{\"productName\":\"샘플상품\",\"merchantId\":\"loginId\",\"merchantName\":\"가맹점명\",\"cardNo\":\"465887**********\",\"admissionYmdt\":\"20170201151722\",\"payHistId\":\"20170201NP1043587781\",\"totalPayAmount\":1000,\"primaryPayAmount\":1000,\"npointPayAmount\":0,\"giftCardAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"primaryPayMeans\":\"CARD\",\"merchantPayKey\":\"청구서UID\",\"merchantUserKey\":\"빌러유저키\",\"cardCorpCode\":\"C0\",\"paymentId\":\"20170201NP1043587746\",\"admissionTypeCode\":\"01\",\"settleExpectAmount\":971,\"payCommissionAmount\":29,\"admissionState\":\"SUCCESS\",\"tradeConfirmYmdt\":\"20170201152510\",\"cardAuthNo\":\"17545616\",\"cardInstCount\":0,\"usedCardPoint\":false,\"bankCorpCode\":\"\",\"bankAccountNo\":\"\",\"settleExpected\":false,\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}}}")
            })
    })
    @Parameters({
            @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH),
    })
    @Operation(summary = "납부(결제)결과")
    @PostMapping(value = "/iup/bill/{paySe}/pay/result", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity payResult(@PathVariable String paySe, @RequestBody Map<String, Object> param) {

        if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe)))
            throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm());
        return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payResult(param), HttpStatus.OK);
    }

    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
            @Content(mediaType = "application/json", examples = {
                    @ExampleObject(name = "nvpay(네이버페이)"
                            , summary = "nvpay(네이버페이)"
                            , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"responseCount\":1,\"totalCount\":1,\"totalPageCount\":1,\"currentPageNumber\":1,\"list\":[{\"cardAuthNo\":\"00000000\",\"bankAccountNo\":\"\",\"bankCorpCode\":\"\",\"paymentId\":\"20170000NP1000229665\",\"cardCorpCode\":\"C0\",\"cardInstCount\":0,\"usedCardPoint\":false,\"settleInfo\":{\"primaryCommissionAmount\":30,\"npointCommissionAmount\":20,\"giftCardCommissionAmount\":0,\"primarySettleAmount\":470,\"npointSettleAmount\":480,\"giftCardSettleAmount\":0,\"totalSettleAmount\":850,\"totalCommissionAmount\":50,\"settleCreated\":true},\"merchantName\":\"나의가맹점\",\"productName\":\"나의상품\",\"payHistId\":\"20170000NP1000229668\",\"merchantId\":\"MID12345\",\"admissionYmdt\":\"20170914163930\",\"tradeConfirmYmdt\":\"20170915163956\",\"totalPayAmount\":1000,\"merchantPayKey\":\"orderKey-91516397\",\"merchantUserKey\":\"빌러유저키\",\"admissionTypeCode\":\"01\",\"primaryPayMeans\":\"CARD\",\"admissionState\":\"SUCCESS\",\"primaryPayAmount\":500,\"npointPayAmount\":500,\"giftCardPayAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"cardNo\":\"123456**********\",\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}]}}")
            })
    })
    @Parameters({
            @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH),
    })
    @Operation(summary = "결제취소정보")
    @PostMapping(value = "/iup/bill/{paySe}/pay/cancel", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity payCancel(@PathVariable String paySe, @RequestBody Map<String, Object> param) {

        if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe)))
            throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm());
        return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payCancel(param), HttpStatus.OK);
    }
}
