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

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.banka.pages.cards.credit.CardTypeAndDesign;
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.support.auth.Credentials;
import cz.moneta.test.harness.support.auth.Key;
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.harness.annotations.Environment.PPE;
import static cz.moneta.test.harness.annotations.Environment.TST1;

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

    NewClientWithCurrentAccountInformation newClientWithCurrentAccount;
    Long accountNumber;
    String birthNumber;
    String testCardForJira;
    String birthNumberForDifferentHolder;

    public void activateDebitCard(Harness harness, Credentials credentials, String cardNumber) {

        String testCardLastNumbers = StringUtils.right(cardNumber, 4);

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

        testCardForJira = cardNumber;
    }

    @Order(1)
    @TestCase(name = "Set up client", environments = {TST1, PPE})
    public void setup(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials, @Key(Keys.ufo.banka.secondBanker) Credentials secondBanker) {
        newClientWithCurrentAccount = harness.dataPrepare()
                .createNewFoCustomerWithCurrentAccountViaWso2(credentials.getUsername());
        accountNumber = Long.parseLong(newClientWithCurrentAccount.getCurrentAccount());
        birthNumber = newClientWithCurrentAccount.getClientData().birthNumber();
        birthNumberForDifferentHolder = harness.getConfig("cards_team.retail.rc2");
        BankaTasks bankaTasks = harness.tasks().ufo().banka();

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

        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumberForDifferentHolder))
                .then(bankaTasks.cardsServicing().confirmPIM());

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

    @Order(2)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Standard plastic debit card for new client", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9376")
    public void standardPlasticDCForExistingClient(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForNewCif(CardTypeAndDesign.STANDARD.getValue(), "Plastic", accountNumber));

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

    @Order(3)
    @EnableIfSet(globalKey = "STANDARD_PLASTIC_DC")
    @TestCase(name = "Check that 2 same plastic cards cant be on 1 account for 1 owner", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9628")
    public void standardPlasticDCForExistingClientFail(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForExistingCurrentAccountFail("Plastic", accountNumber));

        testCardForJira = " Číslo účtu: " + accountNumber.toString();
    }

    @Order(4)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Standard virtual debit card for existing client", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9375")
    public void standardVirtualDCForExistingClient(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForExistingCurrentAccount(CardTypeAndDesign.STANDARD.getValue(), "Virtual", accountNumber));

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

    @Order(5)
    @EnableIfSet(globalKey = "STANDARD_VIRTUAL_DC")
    @TestCase(name = "Check that 2 same virtual cards cant be on 1 account for 1 owner", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9629")
    public void standardVirtualDCForExistingClientFail(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForExistingCurrentAccountFail("Virtual", accountNumber));

        testCardForJira = " Číslo účtu: " + accountNumber.toString();
    }

    @Order(6)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Gold plastic debit card for existing Tom PLUS account", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T12512")
    public void goldPlasticDCForTomPlus(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewGoldDebitCardForExistingCurrentAccount(CardTypeAndDesign.GOLD.getValue(), accountNumber));
    }

    @Order(7)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Gold plastic debit card for existing GOLD account", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T5733")
    public void goldPlasticDCForGoldAccount(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createAccountForGoldCard())
                .then(bankaTasks.cardsOnboarding().createNewGoldDebitCardForNewCurrentAccount("Plastic"));

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

    @Order(8)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Standard virtual debit card for different holder", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9679")
    public void standardVirtualDCForDifferentHolder(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForDifferentHolder(CardTypeAndDesign.STANDARD.getValue(), "Virtual", accountNumber, birthNumberForDifferentHolder));

        Result<Record> resultList = harness.getEndpoint(OdsEndpoint.class).executeSql(CreditCardSQL.FIND_ONBOARDED_CARDS_BY_RC.replaceAll("ID_NUMBER", birthNumberForDifferentHolder));
        testCardForJira = resultList.getValue(0, 1).toString() + " Rč  držitele" + birthNumberForDifferentHolder;
    }

    @Order(9)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "Standard plastic debit card for different holder", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9680")
    public void standardPlasticDCForDifferentHolder(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createNewStandardDebitCardForDifferentHolder(CardTypeAndDesign.STANDARD.getValue(), "Plastic", accountNumber, birthNumberForDifferentHolder));

        Result<Record> resultList = harness.getEndpoint(OdsEndpoint.class).executeSql(CreditCardSQL.FIND_ONBOARDED_CARDS_BY_RC.replaceAll("ID_NUMBER", birthNumberForDifferentHolder));
        testCardForJira = resultList.getValue(0, 1).toString() + " Rč  držitele" + birthNumberForDifferentHolder;
    }

    @Order(10)
    @EnableIfSet(globalKey = "STANDARD_PLASTIC_DC")
    @TestCase(name = "Activate Standard Plastic Debit Card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T35")
    public void activationStandardPlasticDc(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activateDebitCard(harness, credentials, harness.getGlobal("STANDARD_PLASTIC_DC"));
    }

    @Order(11)
    @EnableIfSet(globalKey = "STANDARD_VIRTUAL_DC")
    @TestCase(name = "Check that Virtual Card is Active after onboard", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9716")
    public void activationStandardVirtualDc(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        String testCard = harness.getGlobal("STANDARD_VIRTUAL_DC");
        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().checkDebitCardIsActive(testCardLastNumbers));

        testCardForJira = testCard;
    }

    @Order(12)
    @EnableIfSet(globalKey = "GOLD_PLASTIC_DC")
    @TestCase(name = "Activate Gold Plastic Debit Card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T9717")
    public void activationGoldPlasticDc(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activateDebitCard(harness, credentials, harness.getGlobal("GOLD_PLASTIC_DC"));
    }

    @Order(13)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "EUR debit card for existing EUR account", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T12511")
    public void eurPlasticDCForEurAccount(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createFonAccountWithDifferentCurrency("EUR-BÚ-FO-občan /R/"))
                .then(bankaTasks.cardsOnboarding().createNewDifferentCurrencyCard(CardTypeAndDesign.STANDARD_EUR.getValue(), "Plastic", "|EUR|BÚ - FO - EUR"));

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

    @Order(14)
    @EnableIfSet(globalKey = "SET_UP_OK")
    @TestCase(name = "USD debit card for existing USD account", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T197")
    public void usdPlasticDCForUsdAccount(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        harness.withUfo()
                .openLoginPage()
                .then(bankaTasks.login().withCredentialsAndTurnOffSignpad(credentials))
                .then(bankaTasks.search().findByRC(birthNumber))
                .then(bankaTasks.cardsOnboarding().createFonAccountWithDifferentCurrency("USD-BÚ-FO-občan /R/"))
                .then(bankaTasks.cardsOnboarding().createNewDifferentCurrencyCard(CardTypeAndDesign.STANDARD_USD.getValue(), "Plastic", "|USD|BÚ - FO - USD"));

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

    @Order(15)
    @EnableIfSet(globalKey = "EUR_DC")
    @TestCase(name = "Activate Eur Debit Card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T12513")
    public void activationEurDc(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activateDebitCard(harness, credentials, harness.getGlobal("EUR_DC"));
    }

    @Order(16)
    @EnableIfSet(globalKey = "USD_DC")
    @TestCase(name = "Activate Usd Debit Card", environments = {TST1, PPE})
    @JiraTestCase(id = "CT-T12514")
    public void activationStandardUsdDc(Harness harness, @Key(Keys.ufo.banka.banker) Credentials credentials) {
        activateDebitCard(harness, credentials, harness.getGlobal("USD_DC"));
    }


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