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

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.banka.pages.cards.credit.*;
import cz.moneta.test.dsl.ufo.banka.pages.common.pages.TIS004_S002_SignerSelectionPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.loans.NEP002_S001_ApplicantPage;
import cz.moneta.test.dsl.ufo.banka.pages.loans.NEP028_S001_SignaturePage;
import cz.moneta.test.dsl.ufo.banka.pages.loans.creditCard.*;
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.requests.BAL006_S002_ClientRequestPageTransitions;
import cz.moneta.test.dsl.ufo.banka.tasks.products.NewProductTasks;
import cz.moneta.test.dsl.util.code.lists.HCisAllStavZadosti;
import cz.moneta.test.dsl.util.data.client.NonClient;

import java.util.function.Function;

import static cz.moneta.test.dsl.ufo.banka.pages.loans.PopCheckboxes.*;
import static cz.moneta.test.dsl.ufo.banka.pages.main.codelists.HCisProductClass.CREDIT_CARD;

public class CreditCardsTasks {

    private final Harness harness;
    private NewProductTasks productTasks;

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

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createAndActivateCreditCard(NonClient applicant, int loanAmount, ProductType productType, CardBrand cardBrand) {
        return start -> start
                .then(createNewCreditCardApplicationDetailed(applicant, loanAmount, productType, cardBrand, HCisAllStavZadosti.APPLICATION_CONDITIONALLY_APROVED))
                .then(createAccountsForNewCreditCardWithExistingIbAndBu(loanAmount))
                .then(activateCreditCardWithoutSignatureSelect(productType.getValue(), "OP", applicant.idCardNumber()));
    }

    public Function<NEP002_S001_ApplicantPage, NEP028_S001_SignaturePage> fillCreditCardApplicantInformation(NonClient nonClient) {
        return start -> start.selectMaritalStatusVerificationSource("údaj z OP")
                .selectNoticePeriod("Ne")
                .selectTrialPeriod("Ne")
                .fillIncomeSourceCount(1)
                .fillOtherExpenses(nonClient.otherExpenses())
                .fillMonthlyPayments(nonClient.otherLoanPayments())
                .fillNetMonthlyIncome(nonClient.netMonthlyIncome())
                .fillHouseholdIncome(nonClient.homeIncome())
                .fillAllowances(nonClient.wageDeductions())
                .selectOccupation("manager/ředitel")
                .selectPOP("Potvrzení o příjmu")
                .clickPopCheckbox(SIGNED)
                .clickPopCheckbox(BIRTHNUMBER)
                .clickPopCheckbox(NO_DEPENDANTS)
                .clickPopCheckbox(AGE)
                .clickPopCheckbox(EMPLOYER_STAMP)
                .clickPoPContinue()
                .clickContinue()
                .onSignaturePage();
    }

    public Function<ONC001_S001_QuickCreditCardRequestPage, DOK001_S001_SelectionOfSubmittedDocumentsPage> fillQuickCreditCardRequest(CreditCardsAdvantages advantage, CreditCardsPromo promo, String creditAmount) {
        return start -> start.fillCreditAmountInput(creditAmount)
                .selectAdvantage(advantage.getAdvantage())
                .selectPromoEvent(promo.getPromo())
                .clickWithoutRecommendationCheckbox()
                .clickSendButton()
                .onSelectionOfSubmittedDocumentsPage();
    }

    public Function<ONC001_S001_QuickCreditCardRequestPage, NKK001_S007_QuickCreditCardApplicantInfoPage> fillCreditCardRequestForUpdate(
            CreditCardsAdvantages advantage, CreditCardsPromo promo, String creditAmount, NeedInsurance needInsurance, ProductType productType,
            CardBrand cardBrand) {
        return start -> start.fillCreditAmountInput(creditAmount)
                .selectAdvantage(advantage.getAdvantage())
                .selectPromoEvent(promo.getPromo())
                .clickWithoutRecommendationCheckbox()
                .selectOverdraftInsurance(needInsurance)
                .clickChangeApplicationParameters()
                .dismissCardApplicationAlert()
                .clickSendButton()
                .onQuickCreditCardApplicationDetailsPage()
                .selectProductType(productType)
                .selectCardType(CardType.KARTA_KARTA)
                .selectCardBrand(cardBrand)
                .selectPromo(promo)
                .setRequestedLimit(creditAmount)
                .clickContinueButton();
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewCreditCardApplication(NonClient applicant, int amount) {
        return start -> start
                .then(createNewCreditCardApplication(applicant, amount, HCisAllStavZadosti.NONE));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewCreditCardApplication(NonClient applicant, int amount, HCisAllStavZadosti expectedAppState) {
        return start -> start.createNewProduct(CREDIT_CARD)
                .onCreditCardPage()
                .then(fillCreditCardPage(amount))
                .onSelectionOfSubmittedDocumentsPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(applicant, false))
                .then(finishApplication(expectedAppState.getValue()));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewCreditCardApplicationDetailed(NonClient applicant, int loanAmount, ProductType productType, CardBrand brand, HCisAllStavZadosti expectedAppState) {
        return start -> start
                .createNewProduct(CREDIT_CARD)
                .onCreditCardPage()
                .clickCheckRequestParametersCheckbox()
                .dismissCardApplicationAlert()
                .then(fillCreditCardPage(loanAmount))
                .onCreditCardApplicationDetailsPage()
                .selectProductType(productType)
                .selectCardBrand(brand)
                .clickContinueButton()
                .selectPinDistributionMethod(PinDistributionMethod.POST)
                .dismissPinChargeAlert()
                .dismissClientNotificationAlert()
                .onSelectionOfSubmittedDocumentsPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(applicant, false))
                .then(finishApplication(expectedAppState.getValue()));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewCreditCardApplicationWithPrefilledData(int amount) {
        return start -> start
                .then(createNewCreditCardApplicationWithPrefilledData(amount, HCisAllStavZadosti.NONE));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createNewCreditCardApplicationWithPrefilledData(int amount, HCisAllStavZadosti expectedAppStatus) {
        return start -> start.createNewProduct(CREDIT_CARD)
                .onCreditCardPage()
                .then(fillCreditCardPage(amount))
                .onApplicantPage()
                .then(finishApplication(expectedAppStatus.getValue()));
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createAccountsForNewCreditCardWithExistingIbAndBu(int amount) { //uses application created in the same test
        return createAccountsForNewCreditCardWithExistingIbAndBu(harness.get(NKK006_S001_CreditCardScoringResultPage.APP_ID_STORE), amount);
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> createAccountsForNewCreditCardWithExistingIbAndBu(String applicationId, int amount) {
        return start -> start
                .then(productTasks.showApplicationDetails(applicationId))
                .then(createAccountsWithExistingIbAndBu(amount));
    }

    private Function<BAL006_S002_ClientRequestPageTransitions, HKO101_S001_MainClientPage> createAccountsWithExistingIbAndBu(int amount) {
        return start -> start.then(selectLoanAmountAndContinueUntilSignerSelectionPage(amount))
                .onSignContractPage()
                .then(signApplicationAndContinueUntilCollectionSettings())
                .onClientRequestsPage()
                .clickBackToMainClientPage();
    }

    private Function<BAL006_S002_ClientRequestPageTransitions, TIS004_S002_SignerSelectionPageTransitions> selectLoanAmountAndContinueUntilSignerSelectionPage(int loanAmount) {
        return start -> start
                .onCreditCardScoringResultPage()
                .clickCreateProductAndPrintContract()
                .onSelectingApprovedVariantsPage()
                .clickToLoanAmountRadioButton()
                .typeIntoLoanAmount(String.valueOf(loanAmount))
                .clickSelect()
                .continueToPrintCopyOfContractProposalPage()
                .clickContinue()
                .onSignerSelectionPage()
                .clickContinue();
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> activateCreditCardWithSignatureSelect(String cardType, String idCardType, String idCardNumber) {
        return start -> start.clickActiveProduct(cardType)
                .onCreditCardDetailPage()
                .clickActivateCard()
                .onDebitCardActivation()
                .selectIdCardType(idCardType)
                .fillIdCardNumber(idCardNumber)
                .clickActivateCard()
                .onSignerSelectionPage()
                .clickContinue()
                .onConfirmSignaturePage()
                .clickRightButton()
                .onCreditCardDetailPage()
                .storeProductStat()
                .clickBackToClient();
    }

    public Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> activateCreditCardWithoutSignatureSelect(String cardType, String idCardType, String idCardNumber) {
        return start -> start.clickActiveProduct(cardType)
                .onCreditCardDetailPage()
                .clickActivateCard()
                .onDebitCardActivation()
                .selectIdCardType(idCardType)
                .fillIdCardNumber(idCardNumber)
                .clickActivateCard()
                .onConfirmSignaturePage()
                .clickRightButton()
                .onCreditCardDetailPage()
                .storeProductStat()
                .clickBackToClient();
    }

    private Function<ONC001_S001_NewCreditCardPage, ONC001_S001_NewCreditCardPageTransitions> fillCreditCardPage(int amount) {
        return start -> start.fillAmount(amount)
                .clickNoRecommendation()
                .selectPromo("Bez akce")
                .clickSend();
    }

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

    public Function<HKO101_S001_MainClientPage, NKK004_S001_ProductTransferPage> createProductTransferApplicationWithIdSelection(String currentProduct, NonClient applicant) {
        return start -> start
                .clickActiveProduct(currentProduct)
                .onCreditCardDetailPage()
                .clickProductTransferButton()
                .onIdSelectionPage()
                .then(productTasks.selectIDs())
                .then(productTasks.fillApplicantPage(applicant, false))
                .clickContinue()
                .onProductTransferPage()
                .clickCreditAccount()
                .clickSendButton();
    }

    public Function<HKO101_S001_MainClientPage, NKK004_S001_ProductTransferPage> createProductTransferApplication(String currentProduct, NonClient applicant) {
        return start -> start
                .clickActiveProduct(currentProduct)
                .onCreditCardDetailPage()
                .clickProductTransferButton()
                .then(productTasks.fillApplicantPage(applicant, false))
                .clickContinue()
                .onProductTransferPage()
                .clickCreditAccount()
                .clickSendButton();
    }

    private Function<NEP002_S001_ApplicantPage, HKO101_S001_MainClientPage> finishApplication(String expectedAppState) {
        return start -> start
                .clickContinue()
                .onSignaturePage()
                .then(productTasks.finishLoanApplication())
                .onCreditCardScoringResultPage()
                .then(waitForStatusAndLogData(expectedAppState))
                .clickEnd();

    }

    private Function<OPN008_S001_SignContractPage, INK001_CreditCardCollectionListPageTransitions> signApplicationAndContinueUntilCollectionSettings() {
        return start -> start
                .clickFirstSignerCheckbox()
                .clickYesButton()
                .clickOk()
                .clickContinue()
                .clickContinue()
                .clickBack()
                .clickEnd();
    }

}