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

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.hypos.enums.Client;
import cz.moneta.test.dsl.hypos.pages.contract.ContractHistoryPage;
import cz.moneta.test.dsl.hypos.pages.hypokalkulacka.HypokalkulackaClientDetailPage;
import cz.moneta.test.dsl.hypos.pages.hypokalkulacka.HypokalkulackaPage;
import cz.moneta.test.dsl.util.DateUtils;
import cz.moneta.test.dsl.util.data.hypos.HyposContract;

import java.util.function.Function;

import static cz.moneta.test.dsl.hypos.enums.HyposLogType.TASK;
import static cz.moneta.test.dsl.hypos.tasks.HyposTasks.defaultDateFormat;

public class HypokalkulackaTasks {
    private final Harness harness;
    private final HyposTasks tasks;

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

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientData(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.onHypokalkulackaPage()
                .clickAddClientButton()
                .then(fillClientData(hyposContract, client))
                .clickSaveClientButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addOtherClientData(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.onHypokalkulackaPage()
                .clickAddClientButton()
                .then(fillClientData(hyposContract, client))
                .selectClientRelation(hyposContract.getClients().get(client).getClientRelation())
                .clickSaveClientButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientAddress(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickAddPermanentAddress()
                .clickAllAddressesEqual()
                .fillStreet(hyposContract.getClients().get(client).getNonClient().residencyAddress().getStreet())
                .fillDescriptiveNumber(hyposContract.getClients().get(client).getNonClient().residencyAddress().getDescriptiveNumber())
                .fillCity(hyposContract.getClients().get(client).getNonClient().residencyAddress().getCity())
                .fillZip(hyposContract.getClients().get(client).getNonClient().residencyAddress().getZip())
                .clickSaveAddressButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientIncomeEmployee(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        if (hyposContract.getClients().get(client).getEmployeeIncomes().isEmpty())
            return start -> start;
        return start -> start.onHypokalkulackaPage()
                .clickClientIncomeButton(String.valueOf(client + 1))
                .selectTab("(Z)", "1")
                .fillGrossSalary(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getGrossSalary())
                .fillEmployerIco(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getIco())
                .fillNetSalary(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getNetSalary())
                .fillEmploymentStartDate(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getStartDate())
                .fillEmploymentType(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getType())
                .fillCorpPhone(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getPhone())
                .fillProfession(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getProfession())
                .clickSpecialRelation()
                .selectCurrencyForEmployee(hyposContract.getClients().get(client).getEmployeeIncomes().get(0).getCurrency())
                .addOtherIncomeEmployee(hyposContract, client);
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientIncomeBusiness(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        if (hyposContract.getClients().get(client).getBusinessIncome() == null)
            return start -> start;
        return start -> start.onHypokalkulackaPage()
                .clickClientIncomeButton(String.valueOf(client + 1))
                .selectTab("(P)", "1")
                .fillTurnoverLatest(hyposContract.getClients().get(client).getBusinessIncome().getTurnoverLatest())
                .fillTaxBaseLatest(hyposContract.getClients().get(client).getBusinessIncome().getTaxBaseLatest())
                .fillPaidTax(hyposContract.getClients().get(client).getBusinessIncome().getPaidTax())
                .selectCostAccounting(hyposContract.getClients().get(client).getBusinessIncome().getCostAccounting())
                .fillCode(hyposContract.getClients().get(client).getBusinessIncome().getNaceCode())
                .clickCode(hyposContract.getClients().get(client).getBusinessIncome().getNaceCode())
                .fillTurnoverPenultimate(hyposContract.getClients().get(client).getBusinessIncome().getTurnoverPenultimate())
                .fillTaxBasePenultimate(hyposContract.getClients().get(client).getBusinessIncome().getTaxBasePenultimate())
                .fillBusinessIco(hyposContract.getClients().get(client).getBusinessIncome().getIco())
                .fillBusinessStartDate(hyposContract.getClients().get(client).getBusinessIncome().getStartDate())
                .selectCurrencyForBusiness(hyposContract.getClients().get(client).getBusinessIncome().getCurrency())
                .fillBusinessCorpPhone(harness.tasks().hypos().hyposCommonTasks().getMobilePhoneNumber())
                .clickSaveIncomeButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientIncomeOther(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        if (hyposContract.getClients().get(client).getOtherIncomes().isEmpty())
            return start -> start;
        return start -> start.onHypokalkulackaPage()
                .clickClientIncomeButton(String.valueOf(client+1))
                .selectTab("(O)", "1")
                .setOtherIncomes(hyposContract, client)
                .clickIncomesRental(hyposContract, client)
                .clickSaveIncomeButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addClientExpenditure(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickClientExpenditureButton(String.valueOf(client + 1))
                .setExpenditures(hyposContract)
                .clickSaveExpenditureButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addHouseholds(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickHouseholdButton("1")
                .fillHouseholdwithIncome(hyposContract.getFirstHouseholdIncome().getWithIncome())
                .fillHouseholdWithoutIncome(hyposContract.getFirstHouseholdIncome().getWithoutIncome())
                .clickSaveExpenditureButton()
                .clickHouseholdButton("2")
                .fillHouseholdwithIncome(hyposContract.getSecondHouseholdIncome().getWithIncome())
                .fillHouseholdWithoutIncome(hyposContract.getSecondHouseholdIncome().getWithoutIncome())
                .clickSaveExpenditureButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addSecondHousehold(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickHouseholdButton("2")
                .fillHouseholdwithIncome(hyposContract.getSecondHouseholdIncome().getWithIncome())
                .fillHouseholdWithoutIncome(hyposContract.getSecondHouseholdIncome().getWithoutIncome())
                .clickSaveExpenditureButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addRealtyData(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickAddRealtyButton()
                .selectRealtyType(hyposContract.getRealty().getRealtyType())
                .fillRealtyPrice(hyposContract.getRealty().getRealtyPrice())
                .selectContractRealtion(hyposContract.getRealty().getContractRelation())
                .clickSaveRealtyButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addLoanData(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickEditLoanButton()
                .selectLoanProduct(hyposContract.getLoanProduct())
                .selectLoanAction(hyposContract.getLoanAction())
                .fillLoanAmount(hyposContract.getMortgageLoanAmount())
                .fillLoanMaturity(hyposContract.getMortgageLoanMaturity())
                .fillOwnResources(hyposContract.getMortgageOwnResources())
                .fillOtherResources(hyposContract.getMortgageOtherResources())
                .fillTotalInvestmentIntention(hyposContract.getMortgageLoanAmount())
                .selectLoanObject(hyposContract.getLoanObjectType())
                .selectRealtyPurchaseReason(hyposContract.getPurchaseReason())
                .addLoanPurposes(hyposContract)
                .addCardif(hyposContract)
                .clickSaveLoanButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> addApplicationData(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickEditApplicationButton()
                .selectContactBranch("Praha 4 - BB Centrum")
                .addBirthPlace(hyposContract)
                .addFirstIdentity(hyposContract)
                .addSecondIdentity(hyposContract)
                .selectPep(hyposContract)
                .clickSaveApplicationButton();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> generateAndSignAgreements101() {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickGenerateAgreements101()
                .clickSignAgreements101()
                .fillSignatureByBank(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .fillSignatureByClient(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .clickSaveDocumentSignatures();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> generateAndSignMortgageApplication() {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickGenerateMortgageApplication()
                .clickSignMortgageApplication()
                .fillSignatureByBank(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .fillSignatureByClient(DateUtils.getFormattedTodayDate(defaultDateFormat))
                .clickSaveDocumentSignatures();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> saveHypokalkulacka() {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.onHypokalkulackaPage()
                .clickSaveHypokalkulackaButtonAndCheckAlertText()
                .checkSaveNewHypokalkulackaVersionButtonPresent();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> fillClientDetailIncomeEmployee(HyposContract hyposContract, int client, int income) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickClientIncomeButton(String.valueOf(client + 1))
                .selectTab("(Z)", String.valueOf(income + 1))
                .clickIncomeEmployeeDetails()
                .clickPaidToMmbNoRadio()
                .clickEmploymentAgencyNoRadio()
                .clickCashSalaryNoRadio()
                .clickEmployeeAbroadNoRadio()
                .clickEmployeeShareholderNoRadio()
                .fillPhone(hyposContract.getClients().get(client).getEmployeeIncomes().get(income).getPhone())
                .clickSaveIncomeEmployeeDetail()
                .clickSaveIncomeButton();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setClientDetailIncomeEmployee(HyposContract hyposContract, Client client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickHypokalkulacka()
                .then(fillClientDetailIncomeEmployee(hyposContract, client.getValue(), 0))
                .clickSaveNewHypokalkulackaVersionAndAcceptAlertText()
                .closeHypokalkulackaAndContinueWithContract(hyposContract)
                .clickHomepage();
    }

    public Function<HypokalkulackaPage, HypokalkulackaPage> fillClientDetailIncomeBusiness(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        if (hyposContract.getClients().get(client).getBusinessIncome() == null)
            return start -> start;
        return start -> start.clickClientIncomeButton(String.valueOf(client + 1))
                .selectTab("(P)", "1")
                .clickIncomeBusinessDetails()
                .fillCorpPhone(harness.tasks().hypos().hyposCommonTasks().getMobilePhoneNumber())
                .fillPaidTax(hyposContract.getClients().get(client).getBusinessIncome().getPaidTax())
                .clickBusinessPaidToMmb()
                .clickSaveIncomeBusinessDetail()
                .clickSaveIncomeButton();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> setClientDetailIncomeBusiness(HyposContract hyposContract, Client client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickHypokalkulacka()
                .then(fillClientDetailIncomeBusiness(hyposContract, Integer.parseInt(client.getOrderValue())))
                .clickSaveNewHypokalkulackaVersionAndAcceptAlertText()
                .closeHypokalkulackaAndContinueWithContract(hyposContract)
                .clickHomepage();
    }

    public Function<ContractHistoryPage, ContractHistoryPage> createNewHypokalkulackaVersion(HyposContract hyposContract) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.clickHypokalkulacka()
                .clickSaveNewHypokalkulackaVersionAndAcceptAlertText()
                .closeHypokalkulackaAndContinueWithContract(hyposContract)
                .clickHomepage();
    }

    private Function<HypokalkulackaClientDetailPage, HypokalkulackaClientDetailPage> fillClientData(HyposContract hyposContract, int client) {
        tasks.hyposCommonTasks().hyposLog(TASK, new Object(){}.getClass().getEnclosingMethod().getName());
        return start -> start.fillPinAndSearchPin(hyposContract.getClients().get(client).getNonClient().birthNumber())
                .fillFirstName(hyposContract.getClients().get(client).getNonClient().firstName())
                .fillLastName(hyposContract.getClients().get(client).getNonClient().lastName())
                .selectNationality(hyposContract.getClients().get(client).getNonClient().nationality())
                .fillBirthDate(hyposContract.getClients().get(client).getNonClient().birthDate())
                .fillPhone(hyposContract.getClients().get(client).getNonClient().fixPhoneNumberHome())
                .fillEmail(hyposContract.getClients().get(client).getNonClient().email())
                .selectEducationType(hyposContract.getClients().get(client).getNonClient().educationLevel().getUfoValue())
                .selectStayType(hyposContract.getClients().get(client).getStayType())
                .selectLivingType(hyposContract.getClients().get(client).getLivingType())
                .selectMaritalStatus(hyposContract.getClients().get(client).getNonClient().maritalStatus().getHyposValue())
                .selectHousehold(hyposContract.getClients().get(client).getHousehold())
                .selectEmployee(hyposContract.getClients().get(client).getEmployee());
    }
}