package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process;

import static org.mockito.Mockito.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import cokr.xit.ens.core.utils.CmmnUtil;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoPayApi;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.CustomUrl;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayUrlRespData;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayUrlData;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;

@SpringBootTest
@ActiveProfiles("local-maria")
public class KkoPayUrlServiceTest {

    @InjectMocks
    private KkoPayUrlService kkoPayUrlService;

    @Mock
    private BillKkoPayApi billKkoPayApi;

    @Mock
    private PayUseSysApi payUseSysApi;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    void testCallApi_EmptyOptionalFromPayUseSysApi() {
        String billUid = "testBillUid";
        PayUrlData<BillKkoPay> data = getBillKkoPayPayUrlData();

        KkoPayUrlRespData resDto = KkoPayUrlRespData.builder()
            .billedYearMonth("")
            .ordinal("")
            .expireAt("")
            .parameters(null)
            .customUrl(CustomUrl.builder().build())
            .build();

        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        PayApiRespDTO<KkoPayUrlRespData> dto = PayApiRespDTO.<KkoPayUrlRespData>okBuilder()
            .data(resDto)
            .build();;

        when(payUseSysApi.payUrl(anyString(), any(), any())).thenReturn(ResponseEntity.ok().body(CmmnUtil.toJsonString(dto)));
        kkoPayUrlService.callApi(billUid, data);

        // verify(payUseSysApi).payUrl(eq("testUrl"), any(), any());
        // verify(billKkoPayApi, never()).url(anyString(), anyString(), any());
        // verify(billKkoPayApi, never()).reUrl(anyString(), anyString(), any());
    }

    @Test
    void testCallApi_EmptyOptionalFromBillKkoPayApiUrl() {
        String billUid = "testBillUid";
        PayUrlData<BillKkoPay> data = getBillKkoPayPayUrlData();

        when(payUseSysApi.payUrl(anyString(), any(), any())).thenReturn(ResponseEntity.ok("payUrlResponse"));
        when(billKkoPayApi.url(anyString(), anyString(), any())).thenReturn(ResponseEntity.ok().build());
        when(billKkoPayApi.reUrl(anyString(), anyString(), any())).thenReturn(ResponseEntity.ok("reUrlResponse"));

        kkoPayUrlService.callApi(billUid, data);

        verify(payUseSysApi).payUrl(eq("testUrl"), any(), any());
        verify(billKkoPayApi).url(eq("testBillerCode"), eq("testAuthorization"), any());
        verify(billKkoPayApi).reUrl(eq("testBillerCode"), eq("testAuthorization"), any());
    }

    @Test
    void testCallApi_EmptyOptionalFromBillKkoPayApiReUrl() {
        String billUid = "testBillUid";
        PayUrlData<BillKkoPay> data = getBillKkoPayPayUrlData();

        when(payUseSysApi.payUrl(anyString(), any(), any())).thenReturn(ResponseEntity.ok("payUrlResponse"));
        when(billKkoPayApi.url(anyString(), anyString(), any())).thenReturn(ResponseEntity.ok().build());
        when(billKkoPayApi.reUrl(anyString(), anyString(), any())).thenReturn(ResponseEntity.ok().build());

        kkoPayUrlService.callApi(billUid, data);

        verify(payUseSysApi).payUrl(eq("testUrl"), any(), any());
        verify(billKkoPayApi).url(eq("testBillerCode"), eq("testAuthorization"), any());
        verify(billKkoPayApi).reUrl(eq("testBillerCode"), eq("testAuthorization"), any());
    }

    @Test
    void testCallApi_NullOrgMng() {
        String billUid = "testBillUid";
        PayUrlData<BillKkoPay> data = getBillKkoPayPayUrlData();

        kkoPayUrlService.callApi(billUid, data);

        verify(payUseSysApi, never()).payUrl(anyString(), any(), any());
        verify(billKkoPayApi, never()).url(anyString(), anyString(), any());
        verify(billKkoPayApi, never()).reUrl(anyString(), anyString(), any());
    }

    private static PayUrlData<BillKkoPay> getBillKkoPayPayUrlData() {

        Bill bill = new Bill();
        OrgMng orgMng = new OrgMng();
        orgMng.setKkoBpUrlApi("testUrl");
        orgMng.setKkoBpBillerCode("testBillerCode");
        orgMng.setKkoBpAuthorization("testAuthorization");
        bill.setOrgMng(orgMng);
        //data.setBill(bill);

        BillKkoPay billKkoPay = BillKkoPay.builder()
            .billUid("")
            .billerUserKey("")
            .build();

        PayUrlData<BillKkoPay> data = PayUrlData.<BillKkoPay>builder()
            .bill(bill)
            .billDetail(billKkoPay)
            .build();
        return data;
    }
}

