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

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.hypos.enums.*;
import cz.moneta.test.dsl.hypos.pages.contract.ContractHistoryPage;
import cz.moneta.test.dsl.hypos.pages.contract.approval.CancelContractPage;
import cz.moneta.test.dsl.hypos.pages.contract.approval.ScoringChecklistPage;
import cz.moneta.test.dsl.hypos.pages.contract.documents.DocumentsPage;
import cz.moneta.test.dsl.hypos.pages.contract.fees.FeesPage;
import cz.moneta.test.dsl.hypos.pages.contract.loan.ClientCurrentAcountPage;
import cz.moneta.test.dsl.hypos.pages.contract.loan.LoanPage;
import cz.moneta.test.dsl.hypos.pages.contract.withdrawal.WithdrawalRequestsPage;
import cz.moneta.test.dsl.util.DateUtils;
import cz.moneta.test.dsl.util.data.hypos.HyposContract;
import cz.moneta.test.dsl.util.data.hypos.ScoringParameter;

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

import static cz.moneta.test.dsl.hypos.enums.Client.FIRST_CLIENT;
import static cz.moneta.test.dsl.hypos.enums.HyposLogType.TASK;
import static cz.moneta.test.dsl.hypos.pages.contract.approval.ScoringPage.AP_ID;

public class ContractTasks {
    public static final String defaultDateFormat = "d.M.yyyy";

    private final Harness harness;
    private HyposCommonTasks tasks;

    public ContractTasks(Harness harness) {
        this.harness = harness;
        this.tasks = harness.tasks().hypos().hyposCommonTasks();
    }

    public Function<ContractHistoryPage, FeesPage> cashCollectedFee() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickFees()
                .selectCollectableFee(CollectableFee.FEE_DOWNLOAD_LV_KM)
                .clickCash()
                .checkCollectedFee();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setNoCifForClient(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickClientsToSetCif()
                .setNoCifRadio(hyposContract)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setLifeInsurance() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLifeInsurance()
                .clickLifeInsuranceDetailButton()
                .clickLifeInsuranceEditButton()
                .selectLifeInsuranceState("Klient je pojistitelný")
                .clickSaveLifeInsuranceButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setLoanAndDrawingConditions(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLoan()
                .clickAddNewTransaction()
                .addTranches(hyposContract)
                .clickSaveButton()
                .clickSetDrawingConditions()
                .moveAndCheckConditions(hyposContract)
                .clickReturnButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setNewRealtyAndSupervision(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickRealty()
                .clickSearchRealty()
                .selectRealtyType(hyposContract.getRealty().getSearchByRealtyType())
                .fillAreaName(hyposContract.getRealty().getRegisterArea())
                .clickAutosuggestLink(hyposContract.getRealty().getAutosuggestionText())
                .fillDescriptiveNumber(hyposContract.getRealty().getDescriptiveNumber())
                .fillFlatNumber(hyposContract.getRealty().getFlatNumber())
                .clickSearchButton()
                .clickCreateNewUnit()
                .selectRealtyType(hyposContract.getRealty().getCollateralType())
                .selectPledgeType(hyposContract.getRealty().getPledgeType())
                .clickSaveButton()
                .clickApprovedSupervisionLink()
                .selectAppraiserCompany(hyposContract.getRealty().getAppraiserCompany())
                .selectAppraiserNameByOrder(hyposContract.getRealty().getAppraiserOrder())
                .fillAppraisalDate(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .fillReproductionPrice(hyposContract.getRealty().getRealtyPrice())
                .fillCurrentPrice(hyposContract.getRealty().getRealtyPriceCurrent())
                .clickSendButton()
                .clickBackToUnitDetailLink()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> importChecklistUwDocument() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickApprovalChecklist()
                .clickChecklistLoan()
                .clickAddOtherRqDoc()
                .fillRequestedDoc("Výjimka")
                .selectUwExceptionDocType()
                .saveModalPage()
                .clickUploadUwException()
                .uploadFileChecklist(harness.tasks().common().getFakePdfPath())
                .saveFileChecklist()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setScoringManual() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .clickManualScoring()
                .then(checkChecklistAndSendToScoring());
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setScoringAutomat() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .clickAutomatScoring()
                .then(checkChecklistAndSendToScoring());
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setPrepareContractsState() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickEventsStateBoxLink()
                .clickPrepareContractsStateLink()
                .clickCommentBoxSaveButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setApVerification() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .getApId(harness)
                .clickToApVerification()
                .dragAndDropDocuments()
                .clickSendToApButton()
                .getTaskIds(harness)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> checkScoringResult(List<ScoringParameter> scoringParameters) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .clickScoringDetail(harness.get(AP_ID).toString())
                .checkScoringParametersLimit(scoringParameters)
                .checkScoringParameterApprovalResult(scoringParameters)
                .checkScoringParametersBonity(scoringParameters)
                .checkScoringParametersBonityLtv(scoringParameters)
                .checkScoringParametersStrategy(scoringParameters)
                .checkScoringParametersRefusalReason(scoringParameters)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, CancelContractPage> setCancelContract() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .clickToCancelContract()
                .clickCancelContractByClientCheckbox()
                .clickCancelContractButton()
                .checkCancelContractSuccessText();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setEventsFlagsUw1() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickSetEventsFlagsLink()
                .clickContractFlag(ContractFlag.ACCEPT_UW1.getValue())
                .clickCommentBoxSaveButton()
                .clickSetEventsFlagsLink()
                .clickContractFlag(ContractFlag.ELABORATE_UW1.getValue())
                .clickCommentBoxSaveButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setEventsFlagsUw2() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickSetEventsFlagsLink()
                .clickContractFlag(ContractFlag.SEND_FOLDER_UW2.getValue())
                .clickCommentBoxSaveButton()
                .clickSetEventsFlagsLink()
                .clickContractFlag(ContractFlag.ACCEPT_FOLDER_UW2.getValue())
                .clickCommentBoxSaveButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setEventsFlagsDocumentsReady() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickSetEventsFlagsLink()
                .clickContractFlag(ContractFlag.DOCUMENTS_READY.getValue())
                .clickCommentBoxSaveButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> finishContractApproval(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickScoring()
                .clickApproveTab()
                .setConditionsFulfillmentDate(hyposContract)
                .checkElectronicApprovalProtocolNo()
                .clickApproveContractButton()
                .waitAndClickConfirmApprovalButton()
                .waitUntilContractApproved()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, String> getClientCifInHypos(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickClients()
                .clickOpenClientDetails()
                .checkClientPin(hyposContract.getClients().get(FIRST_CLIENT.getValue()).getNonClient().birthNumber())
                .getClientCif();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> generateLoanContractDocuments() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickDocuments()
                .clickGenerateLoanContractLink()
                .clickAutoVerifyCheckbox()
                .clickSignInPrague()
                .clickGenerateButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> signLoanContractDocuments() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickDocuments()
                .expandLoanContractDocuments()
                .clickSignContractDocuments()
                .fillSignatureDateByClient(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .clickBankerName()
                .clickSave();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setLandAreaRegistrationDates() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickRealty()
                .fillLandAreaRegistryDraftDate(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .fillLandAreaRegistryEntryDate(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .fillLandAreaRegistryLien1stDate(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .clickSaveLandRegistryDates()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setClientCurrentAccount(String currentAccountNumber) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLoan()
                .clickSetCurrentAccount()
                .setCurrentAccount(currentAccountNumber)
                .clickSaveCurrentAccount()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> approveDrawingConditions() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLoan()
                .clickApproveDrawingConditions()
                .approveDrawingConditions()
                .clickSaveAndReturnButton()
                .clickApproveMortgageConditions()
                .approveMortgageConditions()
                .clickSaveAndReturnButton()
                .clickHomepage();
    }

    public Function<ContractHistoryPage, WithdrawalRequestsPage> createNewDrawRequest(HyposContract hyposContract) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        String clientName = String.format("%s %s", hyposContract.getClients().get(FIRST_CLIENT.getValue()).getNonClient().firstName(), hyposContract.getClients().get(FIRST_CLIENT.getValue()).getNonClient().lastName());
        return start -> start.clickWithdrawalRequests()
                .fillDrawDate(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .clickAddDecisionDate()
                .clickClientAccountCheckbox()
                .selectCurrentAccountOwner(clientName)
                .fillLoanAmount(hyposContract.getMortgageLoanAmount())
                .clickSaveButton();
    }

    public Function<ContractHistoryPage, LoanPage> processAndApproveNewDraw() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLoan()
                .clickNewDraw()
                .clickAddNewDraw()
                .clickSaveButton()
                .clickApproveNewDraw();
    }

    public Function<ContractHistoryPage, LoanPage> doDrawInIcbs() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickLoan()
                .clickDoDrawInIcbs()
                .waitDrawInIcbs();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setChecklistClient(Client client) {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.clickApprovalChecklist()
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.IDENTITY_GENERAL, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_EMPLOYEE, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_BUSINESS, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_PARENTAL_CONTRIBUTION, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_DIETS, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_ALIMENT, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_RENTE, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_OTHER_PENSION, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_PROFIT_PORTION, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.INCOME_RENTAL_ALLOWANCE_GROSS, harness)
                .addChecklistDocs(ChecklistTab.CLIENT, client, ChecklistDocCategory.EXPENDITURE, harness)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setChecklistLoan() {
        tasks.hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickApprovalChecklist()
                .clickChecklistLoan()
                .addChecklistDocs(ChecklistTab.LOAN, null, ChecklistDocCategory.GENERAL_GENERAL, harness)
                .addChecklistDocs(ChecklistTab.LOAN, null, ChecklistDocCategory.PURPOSE_GENERAL, harness)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setChecklistAllocatedCollateral () {
        tasks.hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickApprovalChecklist()
                .clickChecklistAllocatedCollateral()
                .addChecklistDocs(ChecklistTab.ALLOCATED_COLLATERAL, null, ChecklistDocCategory.ALLOC_COL, harness)
                .clickHomepage();
    }

    private Function<ScoringChecklistPage, ContractHistoryPage> checkChecklistAndSendToScoring() {
        tasks.hyposLog(TASK, new Object() {}.getClass().getEnclosingMethod().getName());
        return start -> start.fillComment("Testovací komentář")
                .clickHandoverToScoringButton()
                .clickSendToScoringButton()
                .checkScoringApprovalPresent()
                .clickHomepage();
    }

    public Function<DocumentsPage, DocumentsPage> deleteSelectedDocument () {
        tasks.hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickDeleteSelectedDocument()
                .clickDeleteSelectedDocumentConfirm();
    }
}