package cz.moneta.test.regression.cards.jenkinstests;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.banka.pages.cards.credit.ProductType;
import cz.moneta.test.dsl.ufo.banka.pages.loans.creditCard.ONC001_S001_NewCreditCardPage;
import cz.moneta.test.dsl.ufo.banka.tasks.BankaTasks;
import cz.moneta.test.dsl.util.credentials.Keys;
import cz.moneta.test.dsl.util.data.client.NewClientWithCurrentAccountInformation;
import cz.moneta.test.dsl.util.task.retail.cards.constants.CreditCardSQL;
import cz.moneta.test.harness.annotations.EnableIfSet;
import cz.moneta.test.harness.annotations.JiraTestCase;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.annotations.TestScenarioWithOrder;
import cz.moneta.test.harness.endpoints.ods.OdsEndpoint;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.auth.Credentials;
import cz.moneta.test.harness.support.auth.Key;
import cz.moneta.test.harness.support.web.Builders;
import org.apache.commons.lang.StringUtils;
import org.jooq.Record;
import org.jooq.Result;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Order;

import static cz.moneta.test.dsl.ufo.banka.pages.main.codelists.HCisProductClass.CREDIT_CARD;
import static cz.moneta.test.harness.annotations.Environment.PPE;
import static cz.moneta.test.harness.annotations.Environment.TST1;

@TestScenarioWithOrder(name = "Teller must be able to Onboard a Credit Card on new cif")
public class NewRetailCifAndCreditCardsOnboarding {

    NewClientWithCurrentAccountInformation newClientWithCurrentAccount;
    String birthNumberSmart;
    String birthNumberGold;
    String birthNumberCreditAccount;
    String testCardForJira;
    String birthNumberForJira;

    public String createNewClientWithAccountAndSetupPim(Harness harness, Credentials credentials, Credentials secondBanker) {
        newClientWithCurrentAccount = harness.dataPrepare()
                .createNewFoCustomerWithCurrentAccountViaWso2(credentials.getUsername());

        BankaTasks bankaTasks = harness.tasks().ufo().banka();

        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(secondBanker))
                .globalStoreBankerName(harness)
                .then(bankaTasks.search().findByRC(newClientWithCurrentAccount.getClientData().birthNumber()))
                .then(bankaTasks.cardsServicing().setUpPIM());

        return (newClientWithCurrentAccount.getClientData().birthNumber());
    }

    public void activationRetailCC(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, String globalKeyForCard, String birthNumber) {
        String testCard = harness.getGlobal(globalKeyForCard);
        String testCardLastNumbers = StringUtils.right(testCard, 4);

        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsServicing().activateCreditCard(testCardLastNumbers));

        birthNumberForJira = birthNumber;
        testCardForJira = testCard;
    }

    public void onboardingRetailCC(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker, String birthNumber, int amount, ProductType typeOfCC, String storeKey) {
        birthNumberForJira = birthNumber;

        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumberForJira)).createNewProductWithPossibleConsentPage(CREDIT_CARD);

        UfoEndpoint endpoint = harness.getEndpoint(UfoEndpoint.class);
        Builders.newWebFlowBuilder(ONC001_S001_NewCreditCardPage.class, endpoint, harness)
                .then(bankaTasks.cardsOnboarding().createRetailCreditCard(amount, typeOfCC))
                .then(bankaTasks.cardsOnboarding().createRetailCreditCardBeforeVerification());

        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(secondBanker))
                .then(bankaTasks.cardsServicing().secondBankerApplicationRetailSign());

        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumberForJira))
                .then(bankaTasks.cardsOnboarding().createRetailCreditCardAfterVerification());

        Result<Record> resultList = harness.getEndpoint(OdsEndpoint.class).executeSql(CreditCardSQL.FIND_ONBOARDED_CARDS_BY_RC.replaceAll("ID_NUMBER", birthNumberForJira));
        testCardForJira = resultList.getValue(0, 1).toString();
        harness.storeGlobal(storeKey, resultList.getValue(0, 1));
    }

    @Order(1)
    @TestCase(name = "Set up clients", environments = {TST1, PPE})
    public void setup(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker) {
        birthNumberSmart = createNewClientWithAccountAndSetupPim(harness, credentials, secondBanker);
        birthNumberGold = createNewClientWithAccountAndSetupPim(harness, credentials, secondBanker);
        birthNumberCreditAccount = createNewClientWithAccountAndSetupPim(harness, credentials, secondBanker);

        harness.storeGlobal("SET_UP_OK", true);
    }

    @Order(2)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Smart credit card for existing client", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9681")
    public void smartCCForExistingClient(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker) {
        onboardingRetailCC(harness, credentials, secondBanker, birthNumberSmart, 150000, ProductType.MONEYCARD_SMART, "SMART_CC");
    }

    @Order(3)
    @EnableIfSet(globalKey = "SMART_CC")
    @TestCase(name = "Gold credit card for existing client", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9678")
    public void goldCCForExistingClient(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker) {
        onboardingRetailCC(harness, credentials, secondBanker, birthNumberGold, 300000, ProductType.MONEYCARD_GOLD, "GOLD_CC");
    }

    @Order(4)
    @EnableIfSet(globalKey = "SMART_CC")
    @TestCase(name = "Credit Account card for existing client", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9677")
    public void accountCCForExistingClient(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker) {
        onboardingRetailCC(harness, credentials, secondBanker, birthNumberCreditAccount, 200000, ProductType.CREDIT_ACCOUNT, "ACCOUNT_CC");
    }

    @Order(5)
    @EnableIfSet(globalKey = "SMART_CC")
    @TestCase(name = "Activate Smart credit card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9741")
    public void activationSmartCC(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activationRetailCC(harness, credentials, "SMART_CC", birthNumberSmart);
    }

    @Order(6)
    @EnableIfSet(globalKey = "GOLD_CC")
    @TestCase(name = "Activate Gold credit card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9740")
    public void activationGoldCC(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activationRetailCC(harness, credentials, "GOLD_CC", birthNumberGold);
    }

    @Order(7)
    @EnableIfSet(globalKey = "ACCOUNT_CC")
    @TestCase(name = "Activate Account credit card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9742")
    public void activationAccountCC(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activationRetailCC(harness, credentials, "ACCOUNT_CC", birthNumberCreditAccount);
    }

    @AfterEach
    public void tearDown(Harness harness) {
        harness.store("reports.tmfj.execution.comment",
                birthNumberForJira + "\n Číslo karty: " + testCardForJira +
                        "\n" + harness.tasks().ufo().banka().cardsServicing().getPrintedPages());
    }
}
