package cz.moneta.test.sanity.transactional.cards.firstvision.pilotfirstvision;

import com.fasterxml.jackson.annotation.JsonProperty;
import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.wso2.data.CardData;
import cz.moneta.test.harness.annotations.Environment;
import cz.moneta.test.harness.annotations.JiraTestCase;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.annotations.TestScenario;
import cz.moneta.test.harness.support.rest.RawRestRequest;
import cz.moneta.test.sanity.transactional.SmokeData;
import cz.moneta.test.sanity.transactional.cards.firstvision.MESSAGE;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;

import static cz.moneta.test.sanity.transactional.cards.firstvision.Embosser.getEmbosser;
import static cz.moneta.test.sanity.transactional.cards.firstvision.MESSAGE.*;

@TestScenario(name = "Customer inquiry")
public class Inquiry {
    private String account;
    private String card;
    private String embosser;
    private String rc;
    private String offerId;

    @BeforeAll
    public void getInfo(Harness harness) {
        SmokeData smokeData = SmokeData.getInstance(harness);
        CardData creditData = smokeData.getCreditData();
        account = creditData.getAccount();
        card = creditData.getCard();
        embosser = creditData.getName();
        rc = creditData.getRc();
        offerId = "CCP0010001";
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T3139")
    public void VmxEmbosserInqE8V7A(Harness harness) {
        getEmbosser(harness, "E8V7A", card)
                .andAssertFieldValue(VMX_MSGOUT + ".CARD_NBR", card)
                .andAssertFieldValue(VMX_MSGOUT + ".POST_NBR", account)
                .andAssertFieldValue(VMX_MSGOUT + ".EMB_NAME_1", embosser.toUpperCase());
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1898")
    public void VmxAcctToCardInq(Harness harness) {
        getCard(harness, account)
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".OUTPUT_DATA.CARD_TABLE.CARD_NBRS_SEQ.CARD_NBR", card);
    }

    public static RawRestRequest.Response getCard(Harness harness, String account) {
        return harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.ACCT.TO.CARD.INQ", "R8V3B"))
                .addField(VMX_MSGIN, "ACCT_NBR", account)
                .postExtended();
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1900")
    public void VmxAccountInqE8VEA(Harness harness) {
        getAccountDetails(harness, "E8VEA", account)
                .andAssertFieldValue(VMX_MSGOUT + ".ACCT_BS_OUTPUT.ACCT_NBR", account)
                .andAssertFieldValue(VMX_MSGOUT + ".ACCT_BS_OUTPUT.SHORT_NAME", embosser.toUpperCase());
    }

    private RawRestRequest.Response getAccountDetails(Harness harness, String apiVersion, String account) {
        return harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.ACCOUNT.INQ", apiVersion))
                .addField(VMX_MSGIN, "ACCOUNT", account)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P");
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1913")
    public void MCmsCardToCardInqEMEA(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("M.CMS.CARD.TO.CARD.INQ.EMEA", "E8V1"))
                .addField(VMX_MSGIN, "CARD_NBR", card)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".OUTPUT_AREA.OUTPUT_DATA.CARD_NBR", card);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T4623")
    public void LoanCustAcctInqCinema(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.LOAN.CUST.ACCT.INQ.CINEMA", "E8VC"))
                .addField(VMX_MSGIN, "ACCOUNT", account)
                .addField(VMX_MSGIN, "ORG", "861")
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".ACCOUNT_OUTPUT.ACCOUNT", account)
                .andAssertPresent(VMX_MSGOUT + ".LOAN_DATA");
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1919")
    public void VmxCmsAcctSummInqEMEA(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.CMS.ACCT.SUMM.INQ.EMEA", "R8V3"))
                .addField(VMX_MSGIN, "ACCOUNT_NBR", account)
                .addField(VMX_MSGIN, "ORG", "861")
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".OUTPUT-AREA.ACCT_INFO.ACCT_NBR", account)
                .andAssertFieldValue(VMX_MSGOUT + ".OUTPUT-AREA.ACCT_INFO.SHORT_NAME", embosser.toUpperCase());
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1921")
    public void VmxExtendedLookupInq(Harness harness) {
        harness.withWso2()
                .prepareRequestXml()
                .withPath(FV)
                .withPayloadFromFile("regression/transactional/cards/sme/R3-VMX.EXTENDED.LOOKUP.INQ.E8V2.xml")
                .addField(VMX_MSGIN + ".KEY_FLDS.PRIMARY_KEY_FLDS", "ID", rc)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".TXN_DATA.BS_ACCT", account);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T4625")
    public void MCmsPlanViewerInq(Harness harness) {
        String count = harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("M.CMS.PLAN.VIEWER.INQ", "R8V4"))
                .addField("VMX_MSGIN", "ACCT", account)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".ACCT", account)
                .extract(VMX_MSGOUT + ".NBR_RETURNED_ITEMS")
                .textValue();
        Assertions.assertTrue(Integer.valueOf(count) > 0, "no fee plans found on " + account);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T2755")
    public void MOmsAccenrollInqEMEA(Harness harness) {
        String count = harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("M.OMS.ACCTENROLL.INQ.EMEA", "E8V4"))
                .addField(VMX_MSGIN, "ACCT_NBR", account)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .extract(VMX_MSGOUT + ".SVC_RECS_NUM")
                .textValue();
        Assertions.assertTrue(Integer.valueOf(count) > 0, "no discount packages found on " + account);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1927")
    public void VmxAcctInsuranceInq(Harness harness) {
        String insuranceCount = harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.ACCT.INSURANCE.INQ", "E8V2A"))
                .addField(VMX_MSGIN, "ACCOUNT", account)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".ACCOUNT", account)
                .extract(VMX_MSGOUT + ".NBR_INS_PRD").textValue();
        Assertions.assertTrue(Integer.valueOf(insuranceCount) > 0, "No insurance found on account " + account);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T3104")
    public void OmsEnrollInq(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("OMS.ENROLL.INQ", "R8V4"))
                .addField(VMX_MSGIN, "ACCT_NBR", account)
                .addField(VMX_MSGIN, "OFFER_ID", offerId)
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .andAssertFieldValue(VMX_MSGOUT + ".OUTPUT-AREA.OFFER_ID", offerId);

    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1924")
    public void VmxMemoInq(Harness harness) {
        String memoCount = harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.MEMO.INQ", "E8V1"))
                .addField(VMX_MSGIN, "ACCT_NBR", account)
                .addField(VMX_MSGIN, "SVC_FUNC_CD", "N")
                .addField(VMX_MSGIN, "NBR_REC", "20")
                .addField(VMX_MSGIN, "CONT_DATA", new CONT_DATA())
                .postExtended()
                .andAssertFieldValue(SVC_RETURN, "P")
                .extract(VMX_MSGOUT + ".NBR_MEMOS")
                .textValue();

        Assertions.assertTrue(Integer.parseInt(memoCount) > 1, "No memos for account " + account);
    }

    @TestCase(environments = {Environment.TST3, Environment.FVE, Environment.PPE})
    @JiraTestCase(id = "FVP-T1905")
    public void VmxUniquelocateInqEMEA(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath(FV)
                .withPojoPayload(new MESSAGE("VMX.UNIQUELOCATE.INQ.EMEA", "R8V1A"))
                .addField(VMX_MSGIN, "INPUTDATA", new INPUTDATA("A"))
                .addField(VMX_MSGIN + ".INPUTDATA", "NBR", account)
                .postExtended()
                .andAssertFieldValue(VMX_MSGOUT + ".SVC_RTN", "P");
    }

    @Data
    private static class CONT_DATA {
        @JsonProperty("CONT_DATE")
        private String date = "2030-12-20";
        @JsonProperty("CONT_TIME")
        private String time = "010101";
        @JsonProperty("CONT_REC_TYPE")
        private String recType = "M";
    }

    @Data
    @AllArgsConstructor
    private static class INPUTDATA {
        @JsonProperty("SEARCH_TYP")
        private String searchType;
    }
}
