package cz.moneta.test.dsl.ufo.banka.tasks.expres;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.banka.pages.common.pages.OBR001_S001_PrintInstructionPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.common.pages.ZZJ001_S001_MeetingRecordPage;
import cz.moneta.test.dsl.ufo.banka.pages.fon.TIS050_S001_SignerSelectionPage;
import cz.moneta.test.dsl.ufo.banka.pages.loans.*;
import cz.moneta.test.dsl.ufo.banka.pages.loans.expres.*;
import cz.moneta.test.dsl.ufo.banka.pages.main.DOK001_S001_SelectionOfSubmittedDocumentsPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.HKO101_S001_MainClientPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.HKO101_S001_MainClientPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.main.PSP004_S001_PrintPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.client.settings.VDB001_S001_SecondBankerJoiningPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.codelists.HCisAllEvidencniCisloNEP;
import cz.moneta.test.dsl.ufo.banka.pages.main.codelists.HCisProductClass;
import cz.moneta.test.dsl.ufo.banka.pages.requests.BAL006_S002_ClientRequestPage;
import cz.moneta.test.dsl.ufo.banka.pages.requests.BAL006_S002_ClientRequestPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.requests.NEP024_S005_ConfirmationOfReceiptAddPage;
import cz.moneta.test.dsl.ufo.banka.pages.search.HLO001_S001_ClientSearchPage;
import cz.moneta.test.dsl.ufo.banka.tasks.BankaTasks;
import cz.moneta.test.dsl.ufo.banka.tasks.products.NewProductTasks;
import cz.moneta.test.dsl.util.DateUtils;
import cz.moneta.test.dsl.util.code.lists.HCisAllStavZadosti;
import cz.moneta.test.dsl.util.code.lists.HCisDoklady;
import cz.moneta.test.dsl.util.data.client.NonClient;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.web.Lookup;

import java.util.List;
import java.util.function.Function;

import static cz.moneta.test.dsl.ufo.banka.pages.fon.CIF113_S001_ChangeDataFO.CIF_CHANGE_DATA_FO_PAGE_LABEL;
import static cz.moneta.test.dsl.ufo.banka.pages.loans.expres.NEP009_S001_Existing_ApplicationsPage.PAGE_ID;
import static cz.moneta.test.dsl.ufo.banka.pages.requests.BAL006_S002_ClientRequestPage.APPLICATION_TYPE_XPATH;
import static cz.moneta.test.dsl.ufo.banka.pages.requests.BAL006_S002_ClientRequestPage.STATE_STORNO_TD_XPATH;

public class ExpressTasks {

    public static final String APPL_KEY_STORE_KEY = "APPL_KEY";
    public static final String SIGNATURE_DOCUMENT_NAME = "Způsob podpisu";
    public static final String REQUEST_DOCUMENT_NAME = "Žádost";
    public static final String CONTRACT_DOCUMENT_NAME = "Smlouva";
    public static final String ZZJ_DOCUMENT_NAME = "ZZJ";
    private final Harness harness;
    private final NewProductTasks productTasks;

    public ExpressTasks(Harness harness) {
        this.harness = harness;
        this.productTasks = harness.tasks().ufo().banka().newProduct();
    }

    public HousingLoanTasks housingLoanTasks() {
        return new HousingLoanTasks(harness);
    }

    public ExpresLoanDataPreparationTasks expressLoanDataPreparationTasks() {
        return new ExpresLoanDataPreparationTasks(harness);
    }

    public ExpresLoanLoggingTasks housingLoanLoggingTasks() {
        return new ExpresLoanLoggingTasks(harness);
    }

    public Function<NEP024_S005_ConfirmationOfReceiptAddPage, NEP024_S005_ConfirmationOfReceiptAddPage> fillConfirmationOfReceipt(NonClient nonClient) {
        String dateFormat = "dd.MM.yyyy";
        return start -> start
                .fillEmploymentFrom(DateUtils.getDateWithFormat(nonClient.occupationEmploymentFromRaw(), dateFormat))
                .fillNetIncome(String.valueOf(nonClient.netMonthlyIncome()))
                .fillOtherLoanPayments(String.valueOf(nonClient.otherLoanPayments()))
                .fillWageDeductions(String.valueOf(nonClient.wageDeductions()))
                .fillDependendPerson(String.valueOf(nonClient.dependants()))
                .selectSalaryInCash("Ne")
                .fillOccupationInstitutionName(nonClient.employer().getName())
                .fillOccupationInstitutionIco(nonClient.employer().getIco())
                //.fillOccupationInstitutionStreet(nonClient.employer().getAddress().getStreet())
                //.fillOccupationInstitutionDescriptiveNumber(nonClient.employer().getAddress().getDescriptiveNumber())
                //.fillOccupationOrientationNumber(nonClient.employer().getAddress().getOrientationNumber())
                //.fillOccupationInstitutionTown(nonClient.employer().getAddress().getCity())
                //.fillOccupationInstitutionZip(nonClient.employer().getAddress().getZip())
                .selectOccupationStatus(nonClient.occupationStatus().getUfoConfirmationOfReceiptValue())
                .fillDateOfIssue(DateUtils.getDateWithFormat(nonClient.dateOfIssueConfirmationOfReceipt(), dateFormat))
                .checkSignatureAndStampCheckboxes()
                .generatePdf();
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplication(NonClient applicant, int loanAmount, int term, HCisAllStavZadosti expectedAppStat) {
        return start -> start.createNewProduct(HCisProductClass.EXPRESS)
                .onExpressPage()
                .then(fillAmountAndTermAndContinue(loanAmount, term))
                .onIdSelectionPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(applicant, true))
                .then(finishApplication(expectedAppStat.getValue()));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplicationWithExistingAndPrefilledData(int loanAmount, int term, HCisAllStavZadosti expectedAppStat) {
        return start -> start.createNewProduct(HCisProductClass.EXPRESS)
                .onExistingApplicationsPage()
                .clickContinue()
                .then(fillAmountAndTermAndContinue(loanAmount, term))
                .onApplicantPage()
                .then(finishApplication(expectedAppStat.getValue()));
    }

    public Function<HKO101_S001_MainClientPage, NEP002_S001_ApplicantPage> startNewExpressApplicationWithExisting(NonClient applicant, int loanAmount, int term, HCisDoklady idType) {
        return start -> start
                .createNewProduct(HCisProductClass.EXPRESS)
                .then(continueToExpressPage())
                .then(fillAmountAndTermAndContinue(loanAmount, term))
                .onIdSelectionPage()
                .then(productTasks.selectSecondIdDocuments(idType))
                .then(productTasks.fillApplicantPage(applicant, false));
    }


    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplicationWithExisting(NonClient applicant, int loanAmount, int term, HCisAllStavZadosti expectedAppStat, HCisDoklady idType) {

        return startNewExpressApplicationWithExisting(applicant, loanAmount, term, idType)
                .andThen(applicantPage -> applicantPage
                        .then(finishApplication(expectedAppStat.getValue())));
    }


    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplicationWithCoApplicant(NonClient applicant, List<NonClient> coApplicants, int loanAmount, int term, HCisAllStavZadosti expectedAppStat, HCisDoklady idType) {
        return startNewExpressApplicationWithExisting(applicant, loanAmount, term, idType)
                .andThen(applicantPage -> applicantPage
                        .then(fillCoApplicants(coApplicants))
                        .then(finishApplication(expectedAppStat.getValue())));
    }


    public Function<HKO101_S001_MainClientPageTransitions, NEP001_S001_NewExpressPage> continueToExpressPage() {
        UfoEndpoint endpoint = harness.getEndpoint(UfoEndpoint.class);
        if (endpoint.isElementVisible(3, PAGE_ID, Lookup.ID)) {
            return start -> start
                    .onExistingApplicationsPage()
                    .clickContinue();
        } else if (endpoint.isElementVisible(5, CIF_CHANGE_DATA_FO_PAGE_LABEL, Lookup.XPATH)) {
            return start -> start
                    .onChangeDataFO()
                    .clickSend()
                    .onPrintInstructionPage()
                    .clickLeftButton()
                    .then(continueToExpressPageFromEditCif());
        } else {
            return start -> start
                    .onExpressPage();
        }
    }

    public Function<OBR001_S001_PrintInstructionPageTransitions, NEP001_S001_NewExpressPage> continueToExpressPageFromEditCif() {
        UfoEndpoint endpoint = harness.getEndpoint(UfoEndpoint.class);
        if (endpoint.isElementVisible(3, PAGE_ID, Lookup.ID)) {
            return start -> start
                    .onExistingApplicationsPage()
                    .clickContinue();
        } else {
            return start -> start
                    .onExpressPage();
        }
    }

    public Function<HKO101_S001_MainClientPageTransitions, NEP001_S001_NewExpressPage> continueIfExistingApplicationsVisible() {
        UfoEndpoint endpoint = harness.getEndpoint(UfoEndpoint.class);
        if (endpoint.isElementVisible(3, NEP009_S001_Existing_ApplicationsPage.PAGE_ID, Lookup.ID)) {
            return start -> start.onExistingApplicationsPage().clickContinue();
        } else {
            return start -> start
                    .onExpressPage();
        }
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplicationWithCoApplicant(NonClient applicant, NonClient coApplicant, int amount, int term, HCisAllStavZadosti expectedAppStat) {
        return start -> start.createNewProduct(HCisProductClass.EXPRESS)
                .then(continueIfExistingApplicationsVisible())
                .clickFirstCoApplicant()
                .selectFirstCoApplicantRelationshipToMainApplicant("OSTATNÍ")
                .clickFillFirstCoApplicant()
                .fillSearchTerm(coApplicant.birthNumber())
                .clickSearchByRc()
                .clickSearch()
                .onExpressPage()
                .then(fillAmountAndTermAndContinue(amount, term))
                .onIdSelectionPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(applicant, false))
                .selectFirstIncome()
                .clickContinue()
                .onIdSelectionPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(coApplicant, false))
                .selectFirstIncome()
                .clickContinue()
                .onApplicationDataPage()
                .then(productTasks.fillApplicationDataPage("Bez pojištění"))
                .clickApplicantSignatureCheckbox()
                .clickCoApplicantSignatureCheckbox()
                .clickYes()
                .onScoringPage()
                .waitForLoader()
                .onExpressScoringResultPage()
                .then(waitForStatusAndLogData(expectedAppStat.getValue()))
                .clickEnd()
                .onMainClientPage();
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewExpressApplicationWithRegistrationNumber(NonClient nonClient, int amount, int term, HCisAllEvidencniCisloNEP registrationNumber, HCisAllStavZadosti expectedAppStat) {
        return start -> start
                .createNewProduct(HCisProductClass.EXPRESS)
                .onExpressPage()
                .then(fillAmountAndTermAndContinue(amount, term))
                .onIdSelectionPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(nonClient, false))
                .selectRegistrationNumber(registrationNumber.getValue())
                .selectRegistrationNumberReason("falešné doklady/PoP")
                .fillRegistrationNumberComment("Test")
                .clickRegistrationNumberOkButton()
                .then(finishApplication(expectedAppStat.getValue()));
    }

    // client must have IB and Current Account
    public Function<HKO101_S001_MainClientPage, OPN008_S001_ExpressSignaturePage> createAccountsForNewExpressUntilSignature(String secondBankerLastName) {//uses application created in the same test
        return createAccountsForNewExpressUntilSignature(harness.get(NEP006_S001_ExpressScoringResultPage.APP_ID_STORE), secondBankerLastName);
    }

    // client must have IB and Current Account
    public Function<HKO101_S001_MainClientPage, OPN008_S001_ExpressSignaturePage> createAccountsForNewExpressUntilSignature(String applicationId, String secondBankerLastName) {
        return start -> start
                .then(productTasks.showApplicationDetails(applicationId))
                .then(createAccountsWithExistingIbAndBuUntilSignature(secondBankerLastName));
    }

    private Function<BAL006_S002_ClientRequestPageTransitions, OPN008_S001_ExpressSignaturePage> createAccountsWithExistingIbAndBuUntilSignature(String secondBankerLastName) { // client must have IB and Current Account
        return start -> start
                .onExpressScoringResultPage()
                .clickCreateAccounts()
                .onSelectApprovedVariantPage()
                .clickFirstVariant()
                .clickSecondVariant()
                .clickSelect()
                .onScoringPage()
                .waitForLoader()
                .OnPreContractualInformationPrintedPage()
                .continueToPrintCopyOfContractProposalPage()
                .clickContinue()
                .onSecondBankerJoiningPage()
                .fillSurnameInput(secondBankerLastName)
                .clickSearch()
                .selectFirstName()
                .clickContinue()
                .onExpressSignaturePage()
                .clickApplicantCheckbox()
                .clickYesAndDismissAlert();
    }

    public Function<NEP001_S001_NewExpressPage, NEP001_S001_NewExpressPageTransitions> fillAmountAndTermAndContinue(int amount, int term) {
        return start -> start
                .fillAmount(amount)
                .selectTerm(term)
                .clickContinue();
    }

    private Function<NEP006_S001_ExpressScoringResultPage, NEP006_S001_ExpressScoringResultPage> waitForStatusAndLogData(String expectedAppStat) {
        return start -> start
                .waitForStatusAndRefresh(expectedAppStat)
                .storeAppId()
                .storeAppKey()
                .storeAppStat();
    }

    public Function<OPN008_S001_ExpressSignaturePage, HKO101_S001_MainClientPage> finishAccountCreationAfterSecondBankerSignature(HCisAllStavZadosti expectedAppStat) {
        return start -> start.clickCheck()
                .clickContinue()
                .waitForLoader()
                .onContractSignedPage()
                .clickContinueButton()
                .onExpressScoringResultPage()
                .waitForStatusAndRefresh(expectedAppStat.getValue())
                .clickEnd()
                .onListOfRequestsPage()
                .clickBackToMainClientPage();
    }

    public Function<NEP002_S001_ApplicantPage, HKO101_S001_MainClientPage> finishApplication(String expectedAppStat) {
        return start -> start
                .selectFirstIncome()
                .clickContinue()
                .onApplicationDataPage()
                .then(productTasks.fillApplicationDataPage("Bez pojištění"))
                .then(productTasks.finishLoanApplication())
                .onExpressScoringResultPage()
                .storeAppKey()
                .then(waitForStatusAndLogData(expectedAppStat))
                .clickEnd()
                .onMainClientPage();
    }

    public Function<HKO101_S001_MainClientPage, VER017_S001_SecondBankerVerificationStatusPage> createExpressLoan(String coApplicantBirthNumber, int loanAmount, int numberOfInstallments, NonClient nonClient, String bankerName) {
        return start -> start
                .createNewProduct(HCisProductClass.EXPRESS)
                .onExpressPage()
                .then(addCoApplicantAndExpelCoApplicant(coApplicantBirthNumber))
                .fillAmount(loanAmount)
                .clickNumberOfInstallments()
                .selectNumberOfInstallments(numberOfInstallments)
                .clickContinue()
                .onIdSelectionPage()
                .selectIdCardRadio()
                .selectPassportRadio()
                .clickDocumentsCheckAndContinue()
                .onCreditCardApplicantPage()
                .then(productTasks.fillApplicantPage(nonClient, true))
                .selectFirstIncome()
                .clickContinue()
                .onApplicationDataPage()
                .selectInsurance("Bez pojištění")
                .clickSaveButton()
                .onSignerSelectionPage()
                .clickSignedPersonallyPhysicallyAndContinue()
                .onPrintPage()
                .saveDocumentUrl()
                .closePrintWindow()
                .then(productTasks.skipOpFoundPageIfVisible())
                .clickApplicantSignatureCheckbox()
                .clickYes()
                .onExpressScoringResultPage()
                .waitForStatusAndRefresh("Doplň doklady")
                .clickFillInDocuments()
                .continueToClientRequiredDocumentsListPage()
                .clickAddDocument()
                .continueToConfirmationOfReceiptAddPage()
                .then(fillConfirmationOfReceipt(nonClient))
                .continueToScanDocumentsPage()
                .uploadAndAssignFakeIncomeConfirmation()
                .clickContinue()
                .onClientRequiredDocumentsList()
                .clickContinue()
                .waitForStatusAndRefresh("PODMÍNĚNÝ SOUHLAS")
                .clickCreateAccounts()
                .onSelectApprovedVariantPage()
                .clickFirstVariant()
                .fillAmountIfVisibleAndChooseInstallments(loanAmount)
                .clickContinue()
                .saveDocumentUrl()
                .closePrintWindow()
                .onInformationPrintedPage()
                .continueToPrintCopyOfContractProposalPage()
                .clickContinue()
                .onWaitingForModulationPage()
                .waitForModulation(120)
                .onSecondBankerJoiningPage()
                .fillSurnameInput(bankerName)
                .clickSearch()
                .clickContinue()
                .onSecondBankerVerificationPage()
                .storeApplicationId();
    }

    public Function<NEP001_S001_NewExpressPage, NEP001_S001_NewExpressPage> addCoApplicantAndExpelCoApplicant(String coApplicantBirthNumber) {
        return start -> start
                .clickFirstCoApplicant()
                .clickFillFirstCoApplicant()
                .fillSearchTerm(coApplicantBirthNumber)
                .clickSearchByRc()
                .clickSearch()
                .onExpressPage()
                .selectFirstCoApplicantRelationshipToMainApplicant("Manžel/manželka")
                .clickExpelCoApplicant();
    }

    public Function<NEP001_S001_NewExpressPage, NEP001_S001_NewExpressPage> fillAddCoApplicants(List<NonClient> coApplicants, String relationshipToMainApplicant) {
        return start -> {
            if (coApplicants != null && !coApplicants.isEmpty()) {
                start
                        .clickFirstCoApplicant()
                        .clickFillFirstCoApplicant()
                        .fillSearchTerm(coApplicants.get(0).birthNumber())
                        .clickSearchByRc()
                        .clickSearch()
                        .onExpressPage()
                        .selectFirstCoApplicantRelationshipToMainApplicant(relationshipToMainApplicant);
                if (coApplicants.size() > 1) {
                    start
                            .clickSecondCoApplicant()
                            .clickFillSecondCoApplicant()
                            .fillSearchTerm(coApplicants.get(1).birthNumber())
                            .clickSearchByRc()
                            .clickSearch()
                            .onExpressPage()
                            .selectSecondCoApplicantRelationshipToMainApplicant(relationshipToMainApplicant);
                }
            }
            return start;
        };
    }

    public Function<DOK001_S001_SelectionOfSubmittedDocumentsPage, NEP002_S001_ApplicantPage> fillIdPage() {
        return start -> start
                .selectIdCardRadio()
                .selectPassportRadio()
                .clickDocumentsCheckAndContinue()
                .onCreditCardApplicantPage();
    }

    public Function<NEP002_S001_ApplicantPage, NEP002_S001_ApplicantPageTransitions> fillApplicantPage(NonClient applicant) {
        return start -> start
                .fillPaymentsOutsideMMB(applicant.otherLoanPayments())
                .fillOtherMonthlyExpenses(applicant.otherExpenses())
                .fillHouseholdIncome(applicant.homeIncome())
                .selectEachIncome()
                .clickContinue();
    }

    public Function<NEP002_S001_ApplicantPage, NEP002_S001_ApplicantPageTransitions> fillCoApplicantPage(NonClient applicant) {
        return start -> start
                .isSameHouseHold("Ne")
                .then(fillApplicantPage(applicant));
    }

    public Function<NEP002_S001_ApplicantPageTransitions, NEP002_S001_ApplicantPageTransitions> fillCoApplicants(List<NonClient> coApplicants) {
        return start -> {
            if (coApplicants != null && !coApplicants.isEmpty()) {
                for (NonClient coApplicant : coApplicants) {
                    start.onIdSelectionPage()
                            .then(fillIdPage())
                            .then(fillCoApplicantPage(coApplicant));
                }
            }
            return start;
        };
    }

    public Function<NEP001_S004_ApplicationDataPage, NEP001_S004_ApplicationDataPageTransitions> fillApplicationDataPage(boolean isInsurance, String insurance) {
        return start -> {
            start.selectInsurance(insurance);
            if (isInsurance) start.clickNoDisabilityPension();
            return start.clickSaveButton();
        };
    }

    public Function<ZZJ001_S001_MeetingRecordPage, TIS050_S001_SignerSelectionPage> fillMeetingRecordPage() {
        return start -> start
                .clickNoInfoAdded()
                .clickNoComment()
                .clickPaperForm()
                .clickContinue()
                .onSignerSelectionPage();
    }

    public Function<TIS050_S001_SignerSelectionPage, NEP006_S001_ExpressScoringResultPage> signDocuments(boolean isInsurance) {
        return start -> {
            PSP004_S001_PrintPage printPage = start
                    .clickSignedPersonallyPhysicallyAndContinue()
                    .onPrintPage()
                    .saveDocumentUrl(SIGNATURE_DOCUMENT_NAME)
                    .closePrintWindow()
                    .onSignerPage()
                    .clickRightButton()
                    .onPrintPage();
            if (isInsurance) {
                printPage
                        .saveDocumentUrl(ZZJ_DOCUMENT_NAME)
                        .closePrintWindow()
                        .onDocumentsProvidedToClientPage()
                        .clickContinue()
                        .onPrintPage();
            }
            return printPage
                    .saveDocumentUrl(REQUEST_DOCUMENT_NAME)
                    .closePrintWindow()
                    .onSignaturePage()
                    .clickAllSignatureCheckboxes()
                    .clickYes()
                    .onScoringPage()
                    .onExpressScoringResultPage();
        };
    }

    public Function<NEP006_S001_ExpressScoringResultPage, VDB001_S001_SecondBankerJoiningPage> createAccountRequiredOrFirstFirstOption(int clientRequiredAmount, int clientRequiredTerm) {
        return page -> page
                .clickCreateAccounts()
                .onSelectApprovedVariantPage()
                .selectRequiredOrFirstVariation(clientRequiredAmount, clientRequiredTerm)
                .clickSelect()
                .onSecondBankerJoiningPage();
    }

    public Function<PSP004_S001_PrintPage, PSP004_S001_PrintPage> printPreContractExpres() {
        return page -> page
                .saveDocumentUrl("Vysvetlivky")
                .closePrintWindow()
                .onInformationPrintedPage()
                .continueToPrintCopyOfContractProposalPage()
                .clickContinue()
                .onSecondBankerVerificationPage()
                .checkVerificationStatus("Zavstupované dokumenty / doklady byly v pořádku.")
                .clickContinue()
                .onPrintPage();
    }

    public Function<VDB001_S001_SecondBankerJoiningPage, PSP004_S001_PrintPage> verification(String secondBanker) {
        return page -> page
                .fillSurnameInput(secondBanker)
                .clickSearch()
                .selectFirstName()
                .clickContinue()
                .onPrintPage()
                .then(verifyBySecondBanker());
    }

    private Function<PSP004_S001_PrintPage, PSP004_S001_PrintPage> verifyBySecondBanker() {
        harness.tasks().wso2().client().setSecondBankerVerificationStateOk(harness.get(APPL_KEY_STORE_KEY));
        return page -> page;
    }

    public Function<PSP004_S001_PrintPage, NEP006_S001_ExpressScoringResultPage> printContract() {
        return page -> page
                .saveDocumentUrl(CONTRACT_DOCUMENT_NAME)
                .closePrintWindow()
                .onSignContractPage()
                .clickAllSignatureCheckboxes()
                .clickYesButtonToClientContractSignPage()
                .clickLeftButton()
                .onMegaExpressRequestPage();
    }

    public Function<HLO001_S001_ClientSearchPage, NEP006_S001_ExpressScoringResultPage> expresLoanE2ETask(LoanData data) {
        BankaTasks bankaTasks = harness.tasks().ufo().banka();
        return page -> {
            NEP001_S004_ApplicationDataPageTransitions applicationDataPageTransitions = page
                    .then(bankaTasks.search().findByRC(data.getClient().birthNumber()))
                    .createNewProduct(HCisProductClass.EXPRESS)
                    .onExpressPage()
                    .then(fillAddCoApplicants(data.getCoApplicants(), "Bratr/Sestra"))
                    .fillAmount(data.getAmount())
                    .selectTerm(data.getTerm())
                    .clickContinue()
                    .onIdSelectionPage()
                    .then(fillIdPage())
                    .then(fillApplicantPage(data.getClient()))
                    .then(fillCoApplicants(data.getCoApplicants()))
                    .onApplicationDataPage()
                    .then(fillApplicationDataPage(data.isInsurance(), data.getInsuranceName()));

            TIS050_S001_SignerSelectionPage signerSelectionPage = data.isInsurance()
                    ? applicationDataPageTransitions.onMeetingRecordPage()
                    .then(fillMeetingRecordPage())
                    : applicationDataPageTransitions.onSignerSelectionPage();

            return signerSelectionPage
                    .then(signDocuments(data.isInsurance()))
                    .waitForStatusAndRefresh("PODMÍNĚNÝ SOUHLAS")
                    .then(createAccountRequiredOrFirstFirstOption(data.getAmount(), data.getTerm()))
                    .then(verification("Sudra"))
                    .then(printPreContractExpres())
                    .then(printContract());
        };
    }

    public HKO101_S001_MainClientPage cancelAllPendingApplications(List<String> applList, HKO101_S001_MainClientPage ufoWindow) {
        BAL006_S002_ClientRequestPage ufoWindow2 = ufoWindow.selectFromListOfRequests();
        UfoEndpoint endpoint = this.harness.getEndpoint(UfoEndpoint.class);
        if (!applList.isEmpty()) {
            applList.forEach(applicationId -> {
                if (endpoint.isElementPresent(String.format(STATE_STORNO_TD_XPATH, applicationId), Lookup.XPATH))
                    return;

                String xpath = String.format(APPLICATION_TYPE_XPATH, applicationId);
                if (endpoint.getText(xpath, Lookup.XPATH).equals("SmSc")) {
                    ufoWindow2
                            .then(cancelUzofkaPendingApplication(applicationId));
                } else if (endpoint.getText(xpath, Lookup.XPATH).equals("Nobl")) {
                    ufoWindow2
                            .then(cancelNoblPendingApplication(applicationId));
                } else {
                    ufoWindow2
                            .then(cancelPendingApplication(applicationId));
                }
            });
        }
        return ufoWindow2.clickBackToMainPage();
    }

    public Function<BAL006_S002_ClientRequestPage, BAL006_S002_ClientRequestPage> cancelPendingApplication(String applicationId) {
        return start -> start
                .clickRequest(applicationId)
                .clickOpenRequestDetail()
                .onExpressScoringResultPage()
                .clickCancelButton()
                .selectCancellationReason("Stornováno z důvodu nové žádosti")
                .clickConfirmButton()
                .waitForLoader()
                .onExpressScoringResultPage()
                .clickEnd()
                .onListOfRequestsPage();
    }

    public Function<BAL006_S002_ClientRequestPage, BAL006_S002_ClientRequestPage> cancelUzofkaPendingApplication(String applicationId) {
        return start -> start
                .clickRequest(applicationId)
                .clickOpenRequestDetail()
                .onUniverzalRequestModelingPage()
                .clickStorno()
                .selectReason("Stornováno z důvodu nové žádosti")
                .clickSend()
                .clickEndButton()
                .onListOfRequests();

    }

    public Function<BAL006_S002_ClientRequestPage, BAL006_S002_ClientRequestPage> cancelNoblPendingApplication(String applicationId) {
        return start -> start
                .clickRequest(applicationId)
                .clickOpenRequestDetail()
                .onConsolidationScoringPage()
                .clickStorno()
                .selectCancellationReason("Stornováno z důvodu nové žádosti")
                .clickConfirmButton()
                .waitForLoader()
                .onConsolidationScoringPage()
                .clickEnd();
    }
}
