package cz.moneta.test.dsl.payment_engine.tasks;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.payment_engine.PaymentEngineDetailAccountPage;
import cz.moneta.test.dsl.payment_engine.enums.AccountStates;
import cz.moneta.test.dsl.payment_engine.enums.CurrencyPAE;
import cz.moneta.test.dsl.payment_engine.enums.ForeignChannelIdentities;
import cz.moneta.test.dsl.payment_engine.enums.TransactionReasonPAE;
import cz.moneta.test.dsl.payment_engine.home.PaymentEngineHomePage;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_cache24_7.PaymentsEngineCache24SearchAccountsNumber;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_clients.*;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_monitoring.*;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchPage;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchTransactionDetailLifeCycle;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchTransactionFiles;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_transaction.*;
import cz.moneta.test.dsl.util.data.client.NonClient;
import cz.moneta.test.dsl.util.data.payment.PaymentData;
import cz.moneta.test.harness.support.auth.Credentials;

import java.time.LocalDateTime;
import java.util.function.Function;

public class PaymentEngineTasks {

    private final Harness harness;

    public PaymentEngineTasks(Harness harness) {
        this.harness = harness;
    }

    public LoginTasks loginTasks() {
        return new LoginTasks(harness);
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateInstantPayment> createInstantTransactionWithPrefix(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateInstantPaymentFromManualCreate()
                .fillManualData(data.getAmount(), data.getMessageMin1(), data.getDebtorAcc(), data.getCreditorAcc(), data.getBankCode())
                .fillPrefix(data.getAccPrefix())
                .wait3sec()
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateInstantPayment> createInstantTransactionWithoutPrefix(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateInstantPaymentFromManualCreate()
                .fillAmount(data.getAmount())
                .fillMessage(data.getMessageMin1())
                .fillDebtorAcc(data.getDebtorAcc())
                .fillCreditorAcc(data.getCreditorAcc())
                .fillBankCode(data.getBankCode())
                .wait3sec()
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> verifyAndWaitForStatus(String transactionId, TransactionReasonPAE status) {
        return start -> start.clickTransactionAndChooseForVerificationFromCreateManualMenu()
                .pressSearch()
                .fillId(transactionId)
                .searchUnverified()
                .selectTransaction(transactionId)
                .clickVerifyTransaction()
                .clickSubmit()
                .clickSubmitIfStillVisible()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> runCZCTDDistribution(PaymentData data) {
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterCZCTDistributionForm()
                .clickOnRunButton()
                .clickAndRunCZCTDistribution(data.getBankName(), data.getPayScheme(), data.getNextDayDist())
                .closeErrorPopUpIfVisibleCZCT(data.getBankName(), data.getPayScheme(), data.getNextDayDist())
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> searchTransactionAndWaitForStatus(TransactionReasonPAE status, String transactionId) {
        return start -> start.search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineSearchPage, PaymentEngineSearchTransactionFiles> checkTransactionChannelAndStoreFileName(PaymentData data) {
        return start -> start.clickOnTransactionFiles()
                .checkTransactionChannelName(data.getChannelName())
                .storeTransactionFileName(data.getChannelName());
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateDomesticPayment> createDomesticPayment(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateDomesticPaymentFromManualCreate()
                .fillManualData(data.getTransactionType(), data.getAmount(), data.getChannelId(),
                        data.getDebtorAcc(), data.getDebtorName(), data.getCreditorAcc(), data.getBankCodeLong(),
                        data.getMessageMin1(), data.getMessageMin2(), data.getIcbsProfile())
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateDomesticPayment> createDomesticPaymentWithDates(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateDomesticPaymentFromManualCreate()
                .fillManualDataWithoutDebtor(data.getTransactionType(), data.getAmount(), data.getDebtorName(),
                        data.getCreditorAcc(), data.getBankCodeLong(), data.getMessageMin1(),
                        data.getMessageMin2(), data.getIcbsProfile())
                .clickOnExecutionDate()
                .chooseExecutionDate(data.getDateXpath())
                .clickOnDebtorPanel()
                .searchDebtorAccount(data.getDebtorAcc())
                .selectDebtorAccount()
                .acceptDebtorAccount()
                .fillDates(data.getSubmissionDate(), data.getDocumentDate(), data.getDocumentId(), data.getChannelId())
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> sendAndRunCZCTDDistribution(PaymentData data, TransactionReasonPAE status, String transactionId) {
        String nextDayDist = (LocalDateTime.now().getHour() < 14) ? "Ne" : "Ano";
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterCZCTDistributionForm()
                .clickOnRunButton()
                .clickAndRunCZCTDistribution(data.getBankName(), data.getPayScheme(), nextDayDist)
                .closeErrorPopUpIfVisibleCZCT(data.getBankName(), data.getPayScheme(), nextDayDist)
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> runReleaseAfterDispoCheck(TransactionReasonPAE status, String transactionId) {
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .clickOnReleaseAfterDispoCheckForm()
                .enterReleaseAfterDispoCheckForm()
                .clickOk()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> sendAndRunXCTDistribution() {
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterXCTDistribution()
                .clickOnRunButton()
                .clickOnOk()
                .closeErrorPopUpIfVisibleXCT()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> sendAndRunStarBuildDistribution() {
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterStarBuildDistributionForm()
                .clickOnRunButton()
                .selectGenerateNotification()
                .selectGenerateNotificationNo()
                .clickOnOk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> sendAndRunSCTDistribution(PaymentData data) {
        return start -> start.clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .clickOnSCTDistributionForm()
                .enterSCTDistributionForm()
                .clickAndRunSCTDistribution(data.getDistributionGroup(), data.getPayScheme())
                .closeErrorPopUpIfVisible(data.getDistributionGroup(), data.getPayScheme())
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateInstantPayment> createInstantTransactionWithMaxData(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateInstantPaymentFromManualCreate()
                .fillManualMaxData(data.getAmount(), data.getMessageMax1(), data.getVariableSymbol(),
                        data.getSpecificSymbol(), data.getConstantSymbol(), data.getDebtorAcc(),
                        data.getCreditorAcc(), data.getBankCode())
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateDomesticPayment> createDomesticPaymentWithMaxData(PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateDomesticPaymentFromManualCreate()
                .fillManualMaxData(data.getTransactionType(), data.getAmount(), data.getChannelId(),
                        data.getVariableSymbol(), data.getSpecificSymbol(), data.getConstantSymbol(),
                        data.getDebtorAcc(), data.getDebtorName(), data.getCreditorAcc(), data.getBankCodeLong(),
                        data.getMessageMax1(), data.getMessageMax2(), data.getIdentification1(),
                        data.getIdentification2(), data.getIcbsProfile())
                .clickOk()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateXctFI2FIPayment> createXctFI2FIPaymentWithoutBankCode(PaymentData data, CurrencyPAE currency) {
        return start -> start.clickTransactionAndChooseCreateXctFI2FIPaymentFromManualCreate()
                .fillMandatoryData(data.getAmount(), currency.getCurrency(), data.getTrxReference(),
                        data.getPreviousReference(), data.getBicFi(), data.getBicBank(), data.getCreditorName(),
                        data.getClearingPartner(), data.getMessageMax1())
                .clickOnDebtorPanel()
                .searchDebtorAccount(data.getDebtorAcc())
                .selectDebtorAccount()
                .acceptDebtorAccount()
                .clickAccept()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateXctFI2FIPayment> createXctFI2FIPaymentWithBankCode(PaymentData data, CurrencyPAE currency) {
        return start -> start.clickTransactionAndChooseCreateXctFI2FIPaymentFromManualCreate()
                .fillMandatoryData(data.getAmount(), currency.getCurrency(), data.getTrxReference(),
                        data.getPreviousReference(), data.getBicFi(), data.getBicBank(), data.getCreditorName(),
                        data.getClearingPartner(), data.getMessageMax1())
                .fillBankCode(data.getBankCode())
                .clickOnDebtorPanel()
                .searchDebtorAccount(data.getDebtorAcc())
                .selectDebtorAccount()
                .acceptDebtorAccount()
                .clickAccept()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentsEngineCache24SearchAccountsNumber> checkAccountState(String account, AccountStates accountState) {
        return start -> start.clickOnCache24_7()
                .clickOnAccountAndReservation()
                .typeInternalAccountNumberAndClickApply(account)
                .waitForAccountState(harness, accountState.getState());
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateInhouseIfcyPayment> createInhouseIfcyPaymentInCzk(PaymentData data, CurrencyPAE currency) {
        return start -> start.clickTransactionAndChooseCreateInhouseIfcyPaymentFromManualCreate()
                .fillMandatoryData(data.getAmount(), currency.getCurrency(), data.getIcbsProfile())
                .fillChannelId(data.getChannelId())
                .fillOptionalData(data.getVariableSymbol(), data.getSpecificSymbol(), data.getConstantSymbol(),
                        data.getIdentification1(), data.getIdentification2(), data.getMessageMax1(), data.getMessageMax2())
                .clickOnDebtorAccountPanel()
                .searchAccount(data.getDebtorAcc())
                .clickOnSelectAccount()
                .clickOnOk()
                .clickOnCreditorAccountPanel()
                .searchAccount(data.getCreditorAcc())
                .clickOnSelectAccount()
                .clickOnOk()
                .clickAccept()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateInhouseIfcyPayment> createInhouseIfcyPaymentInEur(PaymentData data, CurrencyPAE currency) {
        return start -> start.clickTransactionAndChooseCreateInhouseIfcyPaymentFromManualCreate()
                .fillMandatoryData(data.getAmount(), currency.getCurrency(), data.getIcbsProfile())
                .fillChannelId(data.getChannelId())
                .fillOptionalData(data.getVariableSymbol(), data.getSpecificSymbol(), data.getConstantSymbol(),
                        data.getIdentification1(), data.getIdentification2(), data.getMessageMax1(), data.getMessageMax2())
                .clickOnDebtorAccountPanel()
                .searchAccount(data.getDebtorAcc())
                .clickOnSelectAccount()
                .clickOnOk()
                .clickOnCreditorAccountPanel()
                .searchAccount(data.getCreditorAcc())
                .clickOnSelectAccount()
                .clickOnOk()
                .clickOnExchange()
                .clickAccept()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> createForeignPriorityPayment(PaymentData data, CurrencyPAE currency) {
        return start -> start.clickTransactionAndChooseCreateXctClientPaymentFromCreateManualMenu()
                .clickOnChannelIdentity()
                .selectChannelIdentity(ForeignChannelIdentities.PAE)
                .fillManualData(data.getAmount(), data.getCreditorAcc(), data.getCreditorIban(), data.getMessageMin1(),
                        currency.getCurrency(), data.getCreditorName(), data.getCreditorBic(), data.getBankName())
                .clickToExecutionDateCalendar()
                .chooseTodayExecution()
                .selectPriorityOfTransaction()
                .selectPriorityHigh()
                .selectDebtorByIban(data.getDebtorIban())
                .clickSubmit()
                .storeTransactionId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputPacs009FromCapitol(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputPacs009()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringInstanceFileRecords> checkStatusOfPacs009FromCapitol(TransactionReasonPAE status, String fileName) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectCapPacs009Channel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputPain001FromCapitol(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputPain001()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringInstanceFileRecords> checkStatusOfPain001FromCapitol(TransactionReasonPAE status, String fileName) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectCapPain001Channel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputCFAFromMC(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputCFA()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> checkStatusOfCFAFromMC(TransactionReasonPAE status, String fileName) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectMcCfaChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId()
                .storeEquivalentAmountCzk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringChannelList> checkQueForMTExistence(String tabName) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputMT()
                .clickOnRunButton()
                .clickOnFileTab(tabName)
                .clearQueForMTIfExists();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> storeLastMTId(String tabName) {
        return start -> start.then(checkQueForMTExistence(tabName))
                .clickOnInputMT()
                .clickOnRunButton()
                .storeLastNumberInSequence(harness)
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineRunInstance> storeLastNonpriorityFileId() {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputCERTIS()
                .clickOnRunButton()
                .storeLastNonpriorityNumberInSequence(harness);
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputMTFromSAA(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputMT()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringInstanceFileRecords> checkStatusOfMTFromSAA(String fileName, TransactionReasonPAE status) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectMtFromSaaChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringInstanceLifeCycle> checkStatusOfTransactionsFromSAA(String fileName, TransactionReasonPAE status, String amount, String transactionType) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectMtFromSaaChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId()
                .checkTransactionAmount(amount)
                .clickOnLifeCycleButton()
                .storeIngoingTransactionId()
                .checkTransactionAmount(amount)
                .checkTransactionTypeFee(transactionType)
                .storeFeeTransactionId()
                .storeFeeAmount();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputCCIFromCERTIS(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputCERTIS()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> checkStatusOfCCIFromCERTIS(String fileName, TransactionReasonPAE status) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectCciFromCertisChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId()
                .storeSecondRowAmount()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputTrxFromStarBuild(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputStarBuild()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineMonitoringInstanceFileRecords> verifyAndWaitForStatusOfInputFromStarBuild(String fileName, TransactionReasonPAE status) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusForVerification()
                .clickOnSelectChannel()
                .selectTrxFromStarBuildChannel()
                .clickOnApplyButton()
                .waitForChannelAndVerify(fileName)
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputPAINFromMC(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputPAIN()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> checkStatusOfPAINFromMC(String fileName, TransactionReasonPAE status) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectMcPainChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId()
                .storeEquivalentAmountCzk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> inputCFDFromMC(String filepath) {
        return start -> start.clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputCFD()
                .clickOnRunButton()
                .clickOnUploadFileButton()
                .uploadFile(filepath)
                .clickSendPopupButton()
                .clickOkPopupButton()
                .clickOkButton()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> checkStatusOfCFDFromMC(String fileName, TransactionReasonPAE status) {
        return start -> start.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnSelectChannel()
                .selectMcCfdChannel()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(fileName)
                .waitForStatus(harness, status)
                .storeTransactionId()
                .storeOutgoingTransactionId()
                .storeFirstRowAmount()
                .storeSecondRowAmount()
                .clickOnLifeCycleButton()
                .storeIngoingHd11TransactionId()
                .waitForHd11Status(harness, status.getStatus())
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> createStandingOrderCZ(PaymentData data) {
        return start -> start.clickClientsAndChooseCreateCzStandingOrderFromStandingOrders()
                .fillMandatoryData(data.getTransactionType(), data.getAmount(), data.getPeriod(), data.getDayMonth())
                .fillOptionalData(data.getTransactionName(), data.getDescription(), data.getBranchCode(),
                        data.getVariableSymbol(), data.getSpecificSymbol(), data.getConstantSymbol(),
                        data.getIdentification1(), data.getMessageMax1(), data.getMessageMax2())
                .clickOnDebtorPanel()
                .searchAccount(data.getDebtorAcc())
                .clickOnSelectAccount()
                .selectAccount()
                .clickOnCreditorPanel()
                .searchAccount(data.getCreditorAcc())
                .clickOnSelectAccount()
                .selectAccount()
                .clickOnStartDate()
                .chooseStartDate()
                .clickAccept();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> verifyStandingOrder(PaymentData data) {
        return start -> start.clickClientsAndChooseListOfStandingOrderFromStandingOrders()
                .fillSearchData(data.getDebtorAcc(), data.getCreditorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickApply()
                .storeRootId()
                .clickApprove()
                .clickOk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsListOfStandingOrders> checkStandingOrderStatus(String status, String rootId) {
        return start -> start.clickClientsAndChooseListOfStandingOrderFromStandingOrders()
                .clickOnStatus()
                .selectStatusNull()
                .fillId(rootId)
                .clickApply()
                .checkStatus(status);
    }

    public Function<PaymentEngineClientsListOfStandingOrders, PaymentEngineClientsListOfStandingOrdersTransactions> checkStandingOrderTransactionsPresence(PaymentData data) {
        return start -> start
                .clickOnTransactions()
                .clickFilters()
                .fillSettlementFrom(data.getSettlementDate())
                .clickSearch()
                .checkTransactionIdByDatePresent(data.getSettlementDate())
                .storeTransactionIdByDate(data.getSettlementDate());
    }

    public Function<PaymentEngineClientsListOfStandingOrders, PaymentEngineClientsListOfStandingOrders> editStandingOrder(PaymentData data) {
        return start -> start.clickEdit()
                .editStandingOrder(data.getAmount())
                .clickOk()
                .closeTab()
                .clickClientsAndChooseListOfStandingOrderFromStandingOrders()
                .fillSearchData(data.getDebtorAcc(), data.getCreditorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickApply()
                .storeRootId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> verifyEditingOfStandingOrder(String rootId) {
        return start -> start.clickClientsAndChooseListOfStandingOrderFromStandingOrders()
                .clickOnStatus()
                .selectStatusForVerification()
                .fillId(rootId)
                .clickApply()
                .clickApprove()
                .clickOk()
                .closeTab();
    }

    public Function<PaymentEngineClientsListOfStandingOrders, PaymentEngineClientsListOfStandingOrders> deleteStandingOrder(PaymentData data) {
        return start -> start.clickDelete()
                .clickOk()
                .closeTab()
                .clickClientsAndChooseListOfStandingOrderFromStandingOrders()
                .fillSearchData(data.getDebtorAcc(), data.getCreditorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickApply()
                .storeRootId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineCreateAuthorizationForDirectDebit> createAuthorizationForDirectDebit(PaymentData data) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .clickOnCreateAuthorizationForDirectDebit()
                .clickOnCreditor()
                .fillAccount(data.getCreditorAcc())
                .clickSearchByAccount()
                .selectAccount(data.getCreditorAcc())
                .clickOkInTheWindow()
                .clickOnDebtor()
                .fillAccount(data.getDebtorAcc())
                .clickSearchByAccount()
                .selectAccount(data.getDebtorAcc())
                .clickOkInTheWindow()
                .fillManualDataForDirectDebitWithoutDebtor(data.getTransactionName(), data.getBranchCode(),
                        data.getDescription(), data.getVariableSymbol(), data.getSpecificSymbol(),
                        data.getAmount())
                .fillPeriodType(data.getPeriod())
                .clickOk();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> verifyAuthorizationForDirectDebit(PaymentData data) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .clickOnStatus()
                .selectStatusForVerification()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnApply()
                .storeRootId()
                .clickOnApprove()
                .clickOk();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> checkAuthorizationForDirectDebitStatus(String status, String rootId) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .clickOnStatus()
                .selectStatusNull()
                .fillId(rootId)
                .clickOnApply()
                .checkStatus(status);
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> checkAuthorizationForDirectDebitExistence(PaymentData data, Credentials user1, Credentials user2) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickOnApply()
                .checkAuthorizationForDirectDebitForVerificationNotPresent()
                .clickOnStatus()
                .selectStatusValid()
                .clickOnApply()
                .checkAuthorizationForDirectDebitNotPresent(harness, data, user1, user2);
    }

    public Function<PaymentEngineHomePage, PaymentEngineOutgoingArchivEdit> createInternalRequestForCancellation(String transactionId) {
        return start -> start.clickTransactionAndChooseArchivFromOutgoing()
                .fillId(transactionId)
                .searchUnverified()
                .selectTransaction(transactionId)
                .clickOnManualActions()
                .clickOnRequestForCancellation()
                .clickOk();
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> verifyRequestAndWaitForStatus(String transactionId, TransactionReasonPAE status) {
        return start -> start.clickTransactionAndChooseForVerificationFromOutgoing()
                .pressSearch()
                .fillId(transactionId)
                .searchUnverified()
                .selectTransaction(transactionId)
                .clickOnVerifyTransaction()
                .clickOnAcceptRequest()
                .clickOnOk()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineClientsAuthorizationsForDirectDebits, PaymentEngineClientsAuthorizationsForDirectDebits> editAuthorizationForDirectDebit(PaymentData data) {
        return start -> start.clickOnEditAuthorizationForDirectDebit()
                .editAmount(data.getAmount())
                .clickOk()
                .closeTab()
                .clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickOnApply()
                .storeRootId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> verifyEditingOfAuthorizationsForDirectDebits(String rootId) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .clickOnStatus()
                .selectStatusForVerification()
                .fillId(rootId)
                .clickOnApply()
                .clickOnApprove()
                .clickOk();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> verifyDeleteOfAuthorizationsForDirectDebits(PaymentData data) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .clickOnStatus()
                .selectStatusForVerification()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnApply()
                .clickOnApprove()
                .clickOk();
    }

    public Function<PaymentEngineClientsAuthorizationsForDirectDebits, PaymentEngineClientsAuthorizationsForDirectDebits> deleteAuthorizationForDirectDebitAndStoreRootId(PaymentData data) {
        return start -> start.clickOnDeleteAuthorizationForDirectDebit()
                .clickOk()
                .closeTab()
                .clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnStatus()
                .selectStatusForVerification()
                .clickOnApply()
                .storeRootId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsAuthorizationsForDirectDebits> deleteAuthorizationForDirectDebit(PaymentData data) {
        return start -> start.clickOnClients()
                .clickOnAuthrizationsForDirectDebit()
                .fillManualDataForSearch(data.getCreditorAcc(), data.getDebtorAcc())
                .clickOnApply()
                .clickOnDeleteAuthorizationForDirectDebit()
                .clickOk();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsListOfClients> searchClientAndStoreClientName(String clientId) {
        return start -> start.clickClientsAndChooseListOfClients()
                .waitForAjax()
                .fillClientId(clientId)
                .clickOnApply()
                .waitForAjax()
                .storeClientName();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsListOfClients> checkAndStoreNewClientName(String clientId, NonClient nonClient) {
        return start -> start.clickClientsAndChooseListOfClients()
                .waitForAjax()
                .fillClientId(clientId)
                .clickOnApply()
                .waitForAjax()
                .waitForClientNameChange(harness, nonClient.firstName())
                .storeClientName();
    }

    public Function<PaymentEngineHomePage, PaymentEngineClientsListOfClientsAccounts> searchClientAccount(String clientsAccount) {
        return start -> start.clickClientsAndChooseListOfClientsAccounts()
                .waitForAjax()
                .fillClientsAccount(clientsAccount)
                .clickOnApply();
    }

    public Function<PaymentEngineClientsListOfClientsAccounts, PaymentEngineClientsListOfClientsAccounts> checkClientAccountStateBlocked() {
        return start -> start.clickOnDetail()
                .checkAndUpdateAccountStateIfNotBlocked();
    }

    public Function<PaymentEngineClientsListOfClientsAccounts, PaymentEngineClientsListOfClientsAccounts> checkClientAccountStateActive() {
        return start -> start.clickOnDetail()
                .checkAndUpdateAccountStateIfNotActive();
    }

    public Function<PaymentEngineClientsListOfClientsAccounts, PaymentEngineClientsListOfClientsAccounts> storeClientAccountBranchCode() {
        return start -> start.clickOnDetail()
                .storeBranchCode(harness);
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> editAndReleaseIngoingWaiting(String transactionId, String coverAccIngoing) {
        return start -> start.clickTransactionAndChooseWaitingFromIngoing()
                .clickOnSearchField()
                .searchTransaction(transactionId)
                .clickOnManualActions()
                .clickOnEditRelease()
                .clickOnClearingPartner()
                .chooseClearingPartnerCertis()
                .fillCoverAccountIngoing(coverAccIngoing)
                .clickOk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> verifyIngoing(String transactionId) {
        return start -> start.clickTransactionAndChooseForVerificationFromIngoing()
                .clickOnSearchField()
                .searchTransaction(transactionId)
                .clickOnVerifyOrReject()
                .clickOnVerifyOrRejectStillVisible()
                .clickOnAccept()
                .clickOnOk()
                .closeTab();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineHomePage> checkTransactionDetailAndStoreRefTransactionId() {
        return start -> start.clickOnTransactionDetail()
                .storeRefTransaction(harness)
                .closeTab();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineHomePage> checkLifeCycleAndStoreRowTransactionId(TransactionReasonPAE status) {
        return start -> start.clickOnTransactionDetail()
                .clickOnLifeCycle()
                .waitForStatus(harness, status)
                .storeSecondRowTransactionId()
                .storeSecondRowTransactionAmount()
                .clickOnSecondRowTransaction()
                .clickOnSecondRowTransactionDetail()
                .storeRefTransaction(harness)
                .closeTab();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineHomePage> checkLifeCycleAndStoreThirdRowTransactionId(TransactionReasonPAE status) {
        return start -> start.clickOnTransactionDetail()
                .clickOnLifeCycle()
                .waitForStatus(harness, status)
                .storeThirdRowTransactionId()
                .closeTab();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineSearchTransactionDetailLifeCycle> checkLifeCycleAndStoreRowTransactionIds() {
        return start -> start.clickOnTransactionDetail()
                .clickOnLifeCycle()
                .waitForFifthRow(harness)
                .storeSecondRowTransactionId()
                .storeThirdRowTransactionId()
                .storeForthRowTransactionId()
                .storeFifthRowTransactionId();
    }

    public Function<PaymentEngineHomePage, PaymentEngineDetailAccountPage> storeBalancesFromCache24(PaymentData data) {
        return start -> start.clickOnCache24_7()
                .clickOnAccountAndReservation()
                .typeInternalAccountNumberAndClickApply(data.getDebtorAcc())
                .clickOnAccountDetail()
                .getDispoBalance()
                .getAccBalance();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineHomePage> checkPriorityMT103AndHD21RecordDetail(String distributionDate) {
        return start -> start.clickOnTransactionDetail()
                .clickOnRecordDetail()
                .storeRefTransaction()
                .clickExitFromRecordDetail()
                .clickOnLifeCycle()
                .clickOnHD21()
                .clickOnHD21Detail()
                .clickOnRecordDetail()
                .checkDistributionDate(distributionDate)
                .clickExitFromRecordDetail()
                .closeTab();
    }

    public Function<PaymentEngineSearchPage, PaymentEngineHomePage> checkDebitInitiatorAndIcbsProfilData(PaymentData data) {
        return start -> start.clickOnTransactionDetail()
                .clickOnRecordDetail()
                .checkDebitPostingValue(data.getPostingValue())
                .checkInitiatorValue(data.getInitiatorValue())
                .checkIcbsProfileValue(data.getIcbsProfile())
                .clickExitFromRecordDetail()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> createRequestForSCTOutgoingPaymentStatusInquiry(String transactionId, PaymentData data) {
        return start -> start.clickTransactionAndChooseCreateCreateSCTClaimNonReceipt()
                .fillSCTData(transactionId, data.getInstruction())
                .clickOk()
                .storeRequestId()
                .clickNo();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> createRequestForSCTIngoingPaymentReturn(String transactionId) {
        return start -> start.clickTransactionAndChooseArchivFromIngoing()
                .searchTransaction(transactionId)
                .clickOnManualActions()
                .clickManualActionsIfStillVisible()
                .clickOnReturn()
                .clickOnReasonCode()
                .chooseReasonCodeCust()
                .clickOk()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> searchTransactionBySettlement(PaymentData data, TransactionReasonPAE status) {
        return start -> start.search()
                .typeDebtorAcc(data.getDebtorAcc())
                .waitForSettlementDateFrom()
                .typeSettlementDates(data.getSettlementDateFrom(), data.getSettlementDateTo())
                .selectPayScheme(data.getPayScheme())
                .selectFront(data.getFront())
                .selectReason(status.getStatus())
                .clickSearch()
                .storeSelectedTransactionId()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineHomePage> searchTransactionAndRequestForCancellation(String transactionId, PaymentData data) {
        return start -> start.clickTransactionAndChooseArchivFromDistributionToClearing()
                .fillId(transactionId)
                .searchTransaction()
                .clickOnManualActions()
                .clickManualActionsIfStillVisible()
                .clickOnRequestForCancellationBank()
                .clickOnCode()
                .chooseCode(data.getTransactionCode())
                .clickSubmit()
                .clickSubmitIfStillVisible()
                .closeTab();
    }

    public Function<PaymentEngineHomePage, PaymentEngineSearchPage> verifyDistributionToClearingAndWaitForStatus(String transactionId, TransactionReasonPAE status) {
        return start -> start.clickTransactionAndChooseForVerificationFromDistributionToClearing()
                .clickOnSearchField()
                .searchTransaction(transactionId)
                .clickOnVerifyOrReject()
                .clickOnAcceptStornoBanka()
                .clickOnOk()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, status);
    }

    public Function<PaymentEngineSearchPage, PaymentEngineSearchTransactionDetailLifeCycle> checkLifeCycleAndWaitForStatus(PaymentData data, TransactionReasonPAE status) {
        return start -> start.clickOnTransactionDetail()
                .clickOnLifeCycle()
                .waitForRowStatus(harness, data.getTransactionType(), status);
    }

    public Function<PaymentEngineHomePage, PaymentEngineOutgoingManualEdit> releaseManualOutgoing(String transactionId) {
        return start -> start.clickTransactionAndChooseManualFromOutgoing()
                .clickOnFilterButton()
                .fillTransactionId(transactionId)
                .clickOnSearchButtonAndWaitForResult(transactionId)
                .clickOnManualActions()
                .clickOnRelease()
                .clickOnOKButton();
    }

    public void removeAuthorizationForDirectDebit(PaymentData data, Credentials user1, Credentials user2) {
        harness.withPaymentEngine().closePaymentEngine();

        loginTasks().logInPae(harness, user2)
                .then(deleteAuthorizationForDirectDebit(data));
        harness.withPaymentEngine().closePaymentEngine();

        loginTasks().logInPae(harness, user1)
                .then(verifyDeleteOfAuthorizationsForDirectDebits(data));

        harness.log("Previous Authorization For Direct Debit was successfully deleted.");
    }

    public void assumptionAuthorizationForDirectDebitExistence(PaymentData data, Credentials user1, Credentials user2) {

        loginTasks().logInPae(harness, user1)
                .then(checkAuthorizationForDirectDebitExistence(data, user1, user2));
        harness.withPaymentEngine().closePaymentEngine();
        harness.log("Previous Authorization For Direct Debit was not found.");
    }
}