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

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.banka.pages.cards.debit.OBR003_S001_ClientContractSignPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.common.pages.AML002_S001_AmlSurveyPage;
import cz.moneta.test.dsl.ufo.banka.pages.common.pages.AML002_S001_AmlSurveyPageTransitions;
import cz.moneta.test.dsl.ufo.banka.pages.fon.*;
import cz.moneta.test.dsl.ufo.banka.pages.fon.newCif.CIF111_S001_NewCifDataNavigation;
import cz.moneta.test.dsl.ufo.banka.pages.main.HKO101_S001_MainClientPage;
import cz.moneta.test.dsl.ufo.banka.pages.search.CIF013_S002_ClientNotFoundPage;
import cz.moneta.test.dsl.ufo.banka.pages.search.HLO001_S001_ClientSearchPage;
import cz.moneta.test.dsl.util.DateUtils;
import cz.moneta.test.dsl.util.TestUtils;
import cz.moneta.test.dsl.util.data.client.NonClient;
import cz.moneta.test.harness.endpoints.testautomationdb.TestAutomationDbEndpoint;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.auth.Credentials;
import cz.moneta.test.harness.support.web.Lookup;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.function.Function;

import static cz.moneta.test.dsl.ufo.banka.pages.cards.debit.OBR003_S001_ClientContractSignPage.PAGE_LABEL_XPATH;
import static cz.moneta.test.dsl.ufo.banka.pages.main.HKO101_S001_MainClientPage.CLIENT_CIF_STORE_KEY;

public final class NewClientTasks {

    private final Harness harness;
    private static final String dateFormat = "dd.MM.yyyy";

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

    public HKO101_S001_MainClientPage openUfoAndCreateClient(Harness harness, Credentials credentials, NonClient applicant) {
        return harness.withUfo()
                .openLoginPage()
                .then(harness.tasks().ufo().banka().login().withCredentialsAndSelectFirstOmAndTurnOffSignpad(credentials))
                .closeSearchedHistoryIfVisible()
                .then(createWithIdCard(applicant, credentials.getUsername()));
    }

    /**
     * FOR LOCAL USE ONLY!!! DON'T USE IT ON JENKINS!!!
     * For correct work, parameter endpoints.ufo.banka.url in resources/envs/ must be changed
     * TODO: make it work on Jenkins
     */
    public HKO101_S001_MainClientPage openUfoTomcatAndCreateClient(Harness harness, Credentials credentials, NonClient applicant) {
        return harness.withUfo()
                .openLoginPageTomcat()
                .selectFirstOm()
                .clickContinueButton()
                .onClientSearchPageUfoBanka()
                .then(harness.tasks().ufo().banka().login().turnSignpadOff())
                .then(createWithIdCard(applicant, credentials.getUsername()));
    }

    public HKO101_S001_MainClientPage openUfoAndFindClient(Harness harness, Credentials credentials, String birthNumber) {
        return harness
                .withUfo()
                .openLoginPage()
                .then(harness.tasks().ufo().banka().login().withCredentialsAndSelectFirstOmAndTurnOffSignpad(credentials))
                .closeSearchedHistoryIfVisible()
                .fillSearchTerm(birthNumber)
                .clickSearchByRc()
                .onClientDetailPage()
                .storeClientIdNumber()
                .storeClientFullName()
                .getBirthNumber();
    }

    /**
     * FOR LOCAL USE ONLY!!! DON'T USE IT ON JENKINS!!!
     * For correct work, parameter endpoints.ufo.banka.url in resources/envs/ must be changed
     * TODO: make it work on Jenkins
     */
    public HKO101_S001_MainClientPage openUfoTomcatAndFindClient(Harness harness, Credentials credentials, String birthNumber) {
        return harness
                .withUfo()
                .openLoginPageTomcat()
                .selectFirstOm()
                .clickContinueButton()
                .onClientSearchPageUfoBanka()
                .then(harness.tasks().ufo().banka().login().turnSignpadOff())
                .fillSearchTerm(birthNumber)
                .clickSearchByRc()
                .onClientDetailPage();
    }

    public Function<HLO001_S001_ClientSearchPage, HKO101_S001_MainClientPage> create(String bankerUsername) {
        return create(harness.data().newNonClient(), bankerUsername);
    }

    public Function<HLO001_S001_ClientSearchPage, HKO101_S001_MainClientPage> create(NonClient nonClient, String bankerUsername) {
        return start -> start.then(searchNotExistingClient(nonClient))
                .clickCreateNewCustomer()
                .then(selectDocumentIdCard("OP se strojově čitelnými údaji"))
                .onCreateNewCifpage()
                .then(createCustomerWith(nonClient))
                .then(fillPersonalIdentificationData(nonClient))
                .then(fillPersonClientContacts(nonClient))
                .then(fillIdentificationDocuments(nonClient))
                .fillAdditionalInformation()
                .selectRelationshipToTheBank(nonClient.relationshipToTheBank().getName())
                .then(fillAdditionalData(nonClient))
                .clickConsents()
                .clickContinue()
                .onAmlSurveyPage()
                .then(fillAmlSurvey())
                .then(harness.tasks().ufo().banka().newFopClient().finishAmlSurvey())
                .onAmlSurveyPage()
                .then(harness.tasks().ufo().banka().newFopClient().fillBankersAmlSurvey())
                .onSignerSelectionPage()
                .clickSignedPersonallyPhysicallyAndContinue()
                .onPrintPage()
                .saveDocumentUrl()
                .closePrintWindow()
                .onPrintInstructionPage()
                .clickRightButton()
                .onClientContractSignPage()
                .clickLeftButton()
                .onScanDocumentsPage()
                .clickSkipButton()
                .onMainClientPage()
                .then(logCreatedFoClientDataIntoDatabase(nonClient, bankerUsername))
                .then(harness.tasks().ufo().banka().contactAddress().createContactAddress());
    }

    public Function<AML002_S001_AmlSurveyPage, AML002_S001_AmlSurveyPageTransitions> fillAmlSurveyFon() {
        return start -> start
                .clickIncomeFromBusiness()
                .clickContinue()
                .onAmlSurveyPage()
                .clickNotPoliticallyExposedPerson()
                .clickContinue()
                .onAmlSurveyPage()
                .clickCzechRepublicTaxesResidency()
                .clickContinue()
                .onAmlSurveyPage()
                .clickNotAnotherTaxesResidency()
                .clickContinue()
                .onAmlSurveyPage()
                .clickPrimaryMmbAccountYes()
                .clickContinue()
                .onAmlSurveyPage()
                .clickAccountInDifferentBankNo()
                .clickContinue();
    }

    public Function<AML002_S001_AmlSurveyPage, AML002_S001_AmlSurveyPageTransitions> fillBankersAmlSurveyFon() {
        return start -> start
                .clickPotentialClientNotWithThirdPerson()
                .clickContinue();
    }

    public Function<AML002_S001_AmlSurveyPageTransitions, OBR003_S001_ClientContractSignPageTransitions> finishAmlSurveyFon() {
        return start -> start
                .onPrintPage()
                .saveDocumentUrl()
                .closePrintWindow()
                .onClientContractSignPage()
                .clickCenterButton()
                .onClientContractSignPage()
                .clickLeftButton();
    }

    public Function<SCN001_S001_IdDocumentsCopy, SCN001_S001_IdDocumentsCopyTransitions> selectDocumentIdCard(String idCardType) {
        return start -> start
                .clickIdCard()
                .selectIdCardType(idCardType)
                .clickContinue();
    }

    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillIdentificationDocuments(NonClient nonClient) {
        return start -> start.fillIdentificationDocuments()
                //.selectFirstId("ID card")
                //.fillFirstIdNumber(nonClient.idCardNumber())
                .fillFirstIdValidity(nonClient.idNumberExpiration())
                //.selectFirstIdAuthorities("Česká republika")
                .clickAddSecondId()
                .selectSecondId("Řidičský průkaz")
                .fillSecondIdNumber(nonClient.driverLicenceId())
                .fillSecondIdValidity(nonClient.drivingLicenceExpiration())
                .selectSecondIdAuthorities("Česká republika");
    }

    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillIdentificationDocumentsWithExpiration(NonClient nonClient) {
        return start -> start.fillIdentificationDocuments()
                .fillFirstIdValidity(DateUtils.getDateWithFormat(nonClient.idCard().getValidTo(), dateFormat))
                .clickAddSecondId()
                .selectSecondId("Řidičský průkaz")
                .fillSecondIdNumber(nonClient.driverLicenceId())
                .fillSecondIdValidity(DateUtils.getDateWithFormat(nonClient.driveLicenceExpiryDateRaw(), dateFormat));
    }

    @Deprecated
    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillEmployedData(NonClient nonClient) {
        return start -> start.fillEmployment()
                .selectIncomeType(nonClient.incomeType().getUfoValue())
                .selectIncomeSubtype(nonClient.incomeSubtype().getUfoValue())
                .selectEmployment(nonClient.occupationType().getUfoValue());
    }

    public Function<SZR004_S001_PersonIdentificationInFundamentalRegisters, SZR004_S001_PersonIdentificationInFundamentalRegisters> fillFundamentalRegistersInfo(NonClient nonClient) {
        return start -> start
                .fillFirstName(nonClient.firstName())
                .fillLastName(nonClient.lastName())
                .fillBirthNumber(nonClient.birthNumber())
                .fillBirthDate(nonClient.birthDate())
                .fillDocumentNumber(nonClient.idNumber())
                .clickCzechNationality();
    }

    public Function<CIF009_S002_PersonalDataFON, CIF009_S002_PersonalDataFON> fillPersonalDataFON(NonClient nonClient) {
        return start -> start
                .fillBirthPlace(nonClient.placeOfBirth())
                .clickCzechBirthCountry()
                .clickCzechNationality()
                .clickAddressMagnifyingGlass()
                .fillAddressSearchField("vyskocilova 1b, praha")
                .clickAddressSearch()
                .clickFirstFoundAddress()
                .clickSelectAddress()
                .clickCzechCountry()
                .fillValidUntil(nonClient.idNumberExpiration())
                .clickNotPoliticallyExposedPerson();
    }

    public Function<CIF009_S002_PersonalDataFON, CIF009_S002_PersonalDataFON> fillAdditionalIdentificationDocument(NonClient nonClient) {
        return start -> start
                .clickOtherIdentificationDocument()
                .selectOtherIdentificationDocumentType("Řidičský průkaz")
                .fillOtherIdentificationDocumentNumber(nonClient.driverLicenceId())
                .fillOtherIdentificationDocumentValidUntil(nonClient.drivingLicenceExpiration())
                .clickOtherIdentificationDocumentCzechCountry();
    }

    public Function<CIF009_S002_PersonalDataFON, CIF009_S002_PersonalDataFON> fillAdditionalInformationForScoring(NonClient nonClient) {
        return start -> start
                .selectEducation(nonClient.educationLevel().getUfoValue())
                .fillDependentPersonCount("2")
                .selectMarriageStatus(nonClient.maritalStatus().getUfoValue())
                .selectHousingType("Vlastní dům / byt")
                .fillLivingOnAddressFrom("1.1.2020")
                .selectRelationshipWithBank(nonClient.relationshipToTheBank().getName());
    }

    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillPersonalIdentificationData(NonClient nonClient) {
        return start -> start.fillPersonalIdentificationData()
                .clickBornInCzechButton()
                .fillPlaceOfBirth(nonClient.placeOfBirth())
                .clickToCzechRepublicNationality()
                .fillResidency()
                .fillStreet(nonClient.residencyAddress().getStreet())
                .fillStreetNumber(nonClient.residencyAddress().getDescriptiveNumber())
                .fillStreetOrientationNumber(nonClient.residencyAddress().getOrientationNumber())
                .fillCity(nonClient.residencyAddress().getCity())
                .fillZip(nonClient.residencyAddress().getZip())
                .clickResidencyInCzechRepublic()
                .fillPersonalIdentificationData()
                .selectToEducationLevel(nonClient.educationLevel().getUfoValue());
    }

    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillPersonClientContacts(NonClient nonClient) {
        return start -> start.fillContacts()
                .fillEmail(nonClient.email())
                .fillHomePhone(nonClient.fixPhoneNumberHome())
                .fillMobilePhonePrefix("420")
                .fillMobilePhone(nonClient.mobileNumber());
    }

    public Function<CIF009_S002_PersonalDataFON, CIF009_S002_PersonalDataFON> fillContactInformation(NonClient nonClient) {
        return start -> start
                .fillEmail(nonClient.email())
                .fillMobilePhone(nonClient.mobileNumber());
    }

    private Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> fillAdditionalData(NonClient nonClient) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy");
        String residencySince = dateFormat.format(nonClient.currentAddressSinceRaw());

        return start -> start.fillAdditionalInformation()
                .selectMaritalOfStatus(nonClient.maritalStatus().getUfoValue())
                .clickSjmNo()
                .selectAccommodationType(nonClient.accommodationType().getUfoValue())
                .fillResidencySince(residencySince);
    }

    private Function<HLO001_S001_ClientSearchPage, CIF013_S002_ClientNotFoundPage> searchNotExistingClient(NonClient nonClient) {
        return start -> start.fillSearchTerm(nonClient.birthNumber())
                .closeSearchedHistoryIfVisible()
                .clickSearchByRc()
                .onClientNotFound();
    }

    public Function<CIF111_S016_CreateNewCifPage, CIF111_S001_NewCifDataNavigation> createCustomerWith(NonClient nonClient) {
        return start -> start.fillFirstAndLastNames(nonClient.firstName(), nonClient.lastName())
                .clickCzechCitizenshipRadio()
                .selectIdType("Občanský průkaz")
                .fillIdCardNumber(nonClient.idCardNumber())
                .skipNameCheck()
                .clickContinue()
                .then(harness.tasks().ufo().banka().newClient().skipNotRegisteredWarningIfVisible())
                .tryCloseIdentificationPopup();
    }

    public Function<CIF111_S016_CreateNewCifPageTransitions, CIF111_S001_NewCifDataNavigation> skipNotRegisteredWarningIfVisible() {

        UfoEndpoint endpoint = harness.getEndpoint(UfoEndpoint.class);
        if (endpoint.isElementVisible(2, PAGE_LABEL_XPATH, Lookup.XPATH)) {
            return start -> start
                    .onNotREgisteredWarning()
                    .clickLeftButton()
                    .onCreateNewCifPage()
                    .clickContinue()
                    .onNewCifDataNavigation();
        } else {
            return start -> start
                    .onNewCifDataNavigation();
        }
    }

    public Function<HLO001_S001_ClientSearchPage, HKO101_S001_MainClientPage> createWithIdCard(NonClient nonClient, String bankerUsername) {
        return start -> start.then(searchNotExistingClient(nonClient))
                .clickCreateNewCustomer()
                .then(harness.tasks().ufo().banka().newClient().selectDocumentIdCard("OP se strojově čitelnými údaji"))
                .onCreateNewCifpage()
                .then(createCustomerWith(nonClient))
                .tryCloseIdentificationPopup()
                .then(fillPersonalIdentificationData(nonClient))
                .then(fillPersonClientContacts(nonClient))
                .fillResidency()
                .clickContactAddressSameAsPermanentCheckbox()
                .then(fillIdentificationDocumentsWithExpiration(nonClient))
                .fillAdditionalInformation()
                .then(fillAdditionalData(nonClient))
                .clickConsents()
                .clickContinue()
                .onAmlSurveyPage()
                .then(fillAmlSurvey())
                .then(harness.tasks().ufo().banka().newFopClient().finishAmlSurvey())
                .onAmlSurveyPage()
                .then(harness.tasks().ufo().banka().newFopClient().fillBankersAmlSurvey())
                .onSignerSelectionPage()
                .clickSignedPersonallyPhysicallyAndContinue()
                .onPrintPage()
                .closePrintWindow()
                .onSignerPage()
                .clickRightButton()
                .onScanDocumentsPageDMS001()
                .clickSkipButton()
                .onClientContractSignPage()
                .clickLeftButton()
                .onClientContractSignPage()
                .clickLeftButton()
                .onScanDocumentsPage()
                .clickSkipButton()
                .onMainClientPage()
                .then(logCreatedFoClientDataIntoDatabase(nonClient, bankerUsername));
    }

    public Function<CIF111_S001_NewCifDataNavigation, CIF111_S001_NewCifDataNavigation> checkRegistryLoad(NonClient nonClient) {
        return start -> start.checkRegistryLoad()
                .checkFirstName(nonClient.firstName())
                .checkLastName(nonClient.lastName())
                .checkSexMan()
                .checkBirthNumber(nonClient.birthNumber())
                .checkDateOfBirth(TestUtils.parseBirthDateAsString(nonClient.birthNumber()))
                .checkStreet(nonClient.residencyAddress().getStreet())
                .checkStreetDescriptiveNumber(nonClient.residencyAddress().getDescriptiveNumber())
                .checkStreetOrientationNumber(nonClient.residencyAddress().getOrientationNumber())
                .checkCity(nonClient.residencyAddress().getCity())
                .checkCityPart(nonClient.residencyAddress().getCityPart())
                .checkZip(nonClient.residencyAddress().getZip())
                .checkPostOffice(nonClient.residencyAddress().getCity())
                .checkPlaceOfBirth(nonClient.placeOfBirth())
                .checkBornCountry("Česká republika")
                .checkNationality(nonClient.nationality())
                .checkResidencyCountry("Česká republika")
                .checkFirstIdType("Občanský průkaz")
                .checkFirstIdNumber(nonClient.idCard().getNumber())
                .checkFirstIdValidity(DateUtils.getDateWithFormat(nonClient.idCard().getValidTo(), "d.M.yyyy"))
                .checkControlNumberAndDisabled("");
    }

    public Function<AML002_S001_AmlSurveyPage, AML002_S001_AmlSurveyPageTransitions> fillAmlSurvey() {
        return start -> start
                .clickIncomeFromBusiness()
                .clickContinue()
                .onAmlSurveyPage()
                .clickNotPoliticallyExposedPerson()
                .clickContinue()
                .onAmlSurveyPage()
                .clickCzechRepublicTaxesResidency()
                .clickContinue()
                .onAmlSurveyPage()
                .clickNotAnotherTaxesResidency()
                .clickContinue()
                .onAmlSurveyPage()
                .clickPrimaryMmbAccountYes()
                .clickContinue()
                .onAmlSurveyPage()
                .clickAccountInDifferentBankNo()
                .clickContinue();
    }

    private Function<HKO101_S001_MainClientPage, HKO101_S001_MainClientPage> logCreatedFoClientDataIntoDatabase(NonClient nonClient, String bankerUsername) {
        String createdCustomerCif = harness.get(CLIENT_CIF_STORE_KEY);
        String createdDateTime = harness.tasks().dataPrepareTasks().getStartDateTime();

        UfoEndpoint ufoEndpoint = harness.getEndpoint(UfoEndpoint.class);

        harness.getEndpoint(TestAutomationDbEndpoint.class)
                .insertCreatedClientInfo(createdCustomerCif, nonClient.birthNumber(), null, createdDateTime, bankerUsername, "UFO", ufoEndpoint.getNodeHost());
        return start -> start;
    }
}
