package cz.moneta.test.dsl.ufo.banka.pages.main;

import cz.moneta.test.dsl.ufo.banka.pages.cards.credit.HPO039_S001_MbcDetailPage;
import cz.moneta.test.dsl.ufo.banka.pages.income.FIN001_S001_FinancialIncomeSummaryPage;
import cz.moneta.test.dsl.ufo.banka.pages.loans.flexikredit.HPO003_FlexikreditDetailPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.adc.HPO008_S001_OnlineChannelsPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.client.settings.ADR004_S001_EnterContactAddressPage;
import cz.moneta.test.dsl.ufo.banka.pages.main.codelists.HCisProductClass;
import cz.moneta.test.dsl.ufo.banka.pages.main.signature.patterns.PVX043_S002_SignaturePatternsPage;
import cz.moneta.test.dsl.ufo.banka.pages.po.HPO018_S001_AdcPage;
import cz.moneta.test.dsl.ufo.banka.pages.products.current.account.HPO001_S001_CurrentAccountDetailsPage;
import cz.moneta.test.dsl.ufo.banka.pages.requests.BAL006_S002_ClientRequestPage;
import cz.moneta.test.dsl.ufo.banka.pages.search.HLO001_S001_ClientSearchPage;
import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.web.*;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Assertions;

import static cz.moneta.test.dsl.ufo.banka.pages.main.DMS002_S001_ClientDocumentation.NEW_SCAN;
import static cz.moneta.test.dsl.ufo.banka.pages.main.HKO101_S001_MainClientPage.*;
import static cz.moneta.test.dsl.ufo.operations.shared.SharedElements.LOAD_IMG_DIV_CLASS;

@Wait(value = LOAD_IMG_DIV_CLASS, until = Until.GONE, waitSecondsForElement = 120, by = Lookup.CLASSNAME)
@Wait(value = TABLE_NEW_PRODUCT, waitSecondsForElement = 120, by = Lookup.XPATH)
@Wait(value = {HKO101_S001_PAGE_LABEL_XPATH, NON_EMPTY_CIF_LABEL_XPATH}, waitSecondsForElement = 120, by = Lookup.XPATH)
@Wait(value = SERVICE_OPERATIONS_DIV, waitSecondsForElement = 120)
@StoreElementContent(storeKey = CLIENT_CIF_STORE_KEY, value = NON_EMPTY_CIF_LABEL_XPATH, by = Lookup.XPATH)
@Log(value = CIF_LABEL, template = "Client CIF is {}")
public interface HKO101_S001_MainClientPage extends WebFlow<HKO101_S001_MainClientPage>, StoreAccessor {

    String HKO101_S001_PAGE_LABEL_XPATH = "//div[text()='HKO101_S001']";
    String CLIENT_CIF_STORE_KEY = "CLIENT_CIF";
    String BIRTH_NUMBER_STORE_KEY = "BIRTH_NUMBER";
    String UFO_CLIENT_AVAILABLE_BALANCE_KEY = "UFO_CLIENT_AVAILABLE_BALANCE";
    String FULL_NAME_KEY = "FULL_NAME";
    String ICO_KEY = "ICO";
    String CLIENT_ID_KEY = "CLIENT_ID";
    String CURRENT_ACCOUNT_NUMBER = "CURRENT_ACCOUNT_NUMBER";
    String LOG_BUTTON = "XXX100_T001_X011";
    String COPY_LOG_BUTTON = "XXX100_T001_B003";
    String LOG_DATA_TEXTAREA = "//textarea[@id='XXX100_T001_M001']//following-sibling::input";
    String CIF_LABEL = "XXX001_T002_L101";
    String NON_EMPTY_CIF_LABEL_XPATH = "//div[@id='" + CIF_LABEL + "' and not(text()='')]";
    String BIRTHNUMBER_LABEL = "XXX001_T002_L110";
    String IDCARD_LABEL = "XXX001_T002_L112";
    String SEARCH_BUTTON = "HKO101_S001_S001";
    String EDIT_CIF = "HKO101_S001_S008";
    String ADDRESS_AND_STATEMENTS_DISTRIBUTION_DIV = "HKO101_S001_S009";
    String MENU_GROUP_SIGNATURE_PATTERNS = "HKO101_S001_I008";
    String SIGNATURE_PATTERNS = "HKO101_S001_S005";
    String SERVICE_OPERATIONS_DIV = "HKO101_S001_I005";
    String CLIENT_REQUESTS = "HKO101_S001_S003";
    String FINANCE_INFORMATION = "HKO101_S001_B037";
    String INCOME_MODULE = "HKO101_S001_I007";
    String ELECTRONIC_DOCUMENTATION = "HKO101_S001_S021";
    String FULL_NAME_LABEL = "XXX001_T002_L102";
    String ICO_LABEL = "XXX001_T002_L111";
    String ACTIVE_PRODUCTS_SPAN_XPATH = "//span[contains(@class, 'ufo-Tree-Item')]/span";
    String PRODUCT_GENERAL_INPUT_XPATH = "//table[@id='HKO101_S001_G001_UfoTable']//button[contains(@onclick, \"HKO101_S001_G001_onButtonClick('%s')\")]";
    String EMPOWERMENT_MODEL_ADC = "//span[contains(text(), 'Empowerment Model; Aktivní')]";
    String EXPRES_DETAIL = "//span[contains(text(), 'Expres')]//ancestor::div[@class='gwt-Tree']//span[contains(text(), '%s')]";
    String IB_MK_ADC = "//span[contains(text(), 'Internet Banka heslo/MK; Aktivní')]";
    String BANK_API_ADC = "//span[contains(text(), 'Bank API; Aktivní')]";
    String CURRENT_ACCOUNT_XPATH = "//span[contains(@class, 'ufo-Tree-Item')]/span[contains(text(), 'BÚ')]";
    String CURRENT_ACCOUNT_GENERAL_XPATH = "//span[contains(@class, 'ufo-Tree-Item')]/span[contains(text(), '%s')]";
    String NEW_ACCOUNT_NUMBER = "NEW_ACCOUNT_NUMBER";
    String CURRENT_ACCOUNT_ACTIVE_PRODUCT_XPATH = "//span[contains(text(), 'BÚ-FO- KONTO GENIUS')]";
    String ACTIVE_PRODUCT_GENERAL_XPATH = "//span[contains(text(), '%s')]";
    String ALL_ACTIVE_PRODUCTS = "//div[@class = 'gwt-Tree']/div[@class = 'gwt-TreeItemChildSpan' or @class = 'gwt-TreeItemChildSpanLast']";
    String PAGE_ID_DIV = "//div[@id='XXX100_T001_L008' and contains(text(), 'HKO101_S001')]";
    String ACTIVE_PRODUCT_XPATH = "//div[@id = 'HKO101_S001_T001']//span[contains(text(), '%s')]";
    String TABLE_NEW_PRODUCT = "//table[@id='HKO101_S001_G001_UfoTable']";
    String MBC_XPATH_LABEL = "//span[@class = 'ufo-Tree-Item gwt-TreeItem']/span[contains(text(),'Moneta Business Card')]";
    String KONTOKORENT_XPATH_LABEL = "//span[contains( text(), 'Kontokorent; GB nekom KTK')]";
    String FLEXI_KREDIT_XPATH_SPAN = "//span[contains( text(), 'FLEXIKREDIT')]";
    String FIRST_ACCOUNT_NUMBER_SPAN_XPATH = "//span[text()='Expres Business']/../../following-sibling::div//span/span";
    String ACCOUNT_NUMBER_SPAN_XPATH = "//span[text()='Expres Business']/../../following-sibling::div//span[contains(text(),'%s')]";
    String INSURANCE_PRODUCT_XPATH = "//div[@id='HKO101_S001_T001']//span[contains(text(), 'Pojištění')]/../../following-sibling::div";
    String SAVING_ACCOUNT_LABEL_XPATH = "//span[contains(text(),'SÚ_PRO_podnikání_6_PO')]";
    String DEBIT_CARD_XPATH = "//div[@id='HKO101_S001_T001']//span[text()[contains(.,'PK')]]";

    @Click(value = ELECTRONIC_DOCUMENTATION, andWait = @Wait(NEW_SCAN))
    DMS002_S001_ClientDocumentation clickElectronicDocumentation();

    @GetElementContent(CIF_LABEL)
    String getCif();

    @StoreElementContent(storeKey = CLIENT_ID_KEY, value = IDCARD_LABEL)
    HKO101_S001_MainClientPage storeClientIdNumber();

    @StoreElementContent(storeKey = BIRTH_NUMBER_STORE_KEY, value = BIRTHNUMBER_LABEL)
    HKO101_S001_MainClientPage getBirthNumber();

    @CheckElementContent(value = ACTIVE_PRODUCTS_SPAN_XPATH, by = Lookup.XPATH)
    HKO101_S001_MainClientPage checkProductActive(String productName);

    @CheckElementPresent(value = ALL_ACTIVE_PRODUCTS, by = Lookup.XPATH)
    HKO101_S001_MainClientPage verifyThatClientHasSomeActiveProducts();

    @CustomAction
    default HKO101_S001_MainClientPage verifyClientsProductsNotEmpty() {
        UfoEndpoint endpoint = this.getEndpoint(UfoEndpoint.class);
        Assertions.assertNotEquals("", endpoint.getText(ALL_ACTIVE_PRODUCTS, Lookup.XPATH));
        return null;
    }

    @CheckElementPresent(value = SAVING_ACCOUNT_LABEL_XPATH, by = Lookup.XPATH)
    HKO101_S001_MainClientPage verifySavingAccountEstablishedSuccessfully();

    @StoreElementContent(storeKey = FULL_NAME_KEY, value = FULL_NAME_LABEL)
    HKO101_S001_MainClientPage storeClientFullName();

    @StoreElementContent(storeKey = ICO_KEY, value = ICO_LABEL)
    HKO101_S001_MainClientPage storeIco();

    @Click(EDIT_CIF)
    HKO101_S001_MainClientPageTransitions clickEdit();

    @Wait(value = TABLE_NEW_PRODUCT, waitSecondsForElement = 60, by = Lookup.XPATH)
    @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE)
    @Click(value = PRODUCT_GENERAL_INPUT_XPATH, by = Lookup.XPATH)
    HKO101_S001_MainClientPageTransitions createNewProduct(HCisProductClass appType);

    @Wait(value = TABLE_NEW_PRODUCT, waitSecondsForElement = 60, by = Lookup.XPATH)
    @CustomAction
    default void createNewProductWithPossibleConsentPage(HCisProductClass appType) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.jsClick(() -> String.format(PRODUCT_GENERAL_INPUT_XPATH, appType.getValue()), Lookup.XPATH);
    }

    @CustomAction
    default HKO101_S001_MainClientPage clickSignaturePatterns() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> MENU_GROUP_SIGNATURE_PATTERNS);
        endpoint.click(() -> SIGNATURE_PATTERNS);
        return null;
    }

    PVX043_S002_SignaturePatternsPage clickSignaturePatternsPage();

    @CustomAction
    default HKO101_S001_MainClientPage verifyThatCifIsValid() {
        Assertions.assertTrue(StringUtils.isNotBlank(this.getCif()));
        return null;
    }

    @CustomAction
    default void verifyThatCifIs(String expectedCif) {
        Assertions.assertEquals(expectedCif, this.getCif(), "We got wrong CIF");
    }

    @CheckElementContent(BIRTHNUMBER_LABEL)
    HKO101_S001_MainClientPage checkBirthNumberLabel(String expectedBirthNumber);

    @CheckElementContent(IDCARD_LABEL)
    HKO101_S001_MainClientPage checkIdCardLabel(String expectedIdCard);

    @CustomAction
    default HPO018_S001_AdcPage clickEmpowermentModel() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.jsClick(() -> EMPOWERMENT_MODEL_ADC, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> EMPOWERMENT_MODEL_ADC, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO011_S001_ExpresDetailPage clickExpresDetail(String currentAccountNumber) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String xpath = String.format(EXPRES_DETAIL, currentAccountNumber);
        endpoint.jsClick(() -> xpath, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> xpath, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO001_S001_CurrentAccountDetailsPage openCurrentAccountDetailPage() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.jsClick(() -> CURRENT_ACCOUNT_ACTIVE_PRODUCT_XPATH, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> CURRENT_ACCOUNT_ACTIVE_PRODUCT_XPATH, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HKO101_S001_MainClientPageTransitions openProductDetail(String productName) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String productXpath = String.format(ACTIVE_PRODUCT_GENERAL_XPATH, productName);
        endpoint.jsClick(() -> productXpath, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> productXpath, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default ADR004_S001_EnterContactAddressPage clickAddContactAddressAndStatementsDistribution() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> SERVICE_OPERATIONS_DIV);
        endpoint.click(() -> ADDRESS_AND_STATEMENTS_DISTRIBUTION_DIV);
        return null;
    }

    @CustomAction
    default HPO008_S001_OnlineChannelsPage clickInternetBankWithMobileKey() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.jsClick(() -> IB_MK_ADC, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> IB_MK_ADC, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO008_S001_OnlineChannelsPage clickBankApi() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.jsClick(() -> BANK_API_ADC, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> BANK_API_ADC, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HKO101_S001_MainClientPage getCurrentAccountNumberAndStore() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        store(CURRENT_ACCOUNT_NUMBER, endpoint.getText(CURRENT_ACCOUNT_XPATH, Lookup.XPATH).split(";")[1].trim());
        return null;
    }

    @CustomAction
    default HKO101_S001_MainClientPage getNewAccountNumberByNameAndStore(String accountName) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String xpath = String.format(CURRENT_ACCOUNT_GENERAL_XPATH, accountName);
        store(NEW_ACCOUNT_NUMBER, endpoint.getText(xpath, Lookup.XPATH).split(";")[1].trim());
        return null;
    }

    @StoreElementContent(storeKey = UFO_CLIENT_AVAILABLE_BALANCE_KEY, value = CURRENT_ACCOUNT_XPATH, by = Lookup.XPATH)
    HKO101_S001_MainClientPage getCurrentAccountAvailableBalance();

    @CheckElementPresent(value = PAGE_ID_DIV, by = Lookup.XPATH)
    HKO101_S001_MainClientPage checkPageId();

    @CustomAction
    default HPO021_S001_ExpresBusinessDetailPage clickExpresKomexDetail(String currentAccountNumber) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String xpath = String.format(EXPRES_DETAIL, currentAccountNumber);
        endpoint.jsClick(() -> xpath, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> xpath, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HKO101_S001_MainClientPageTransitions clickActiveProduct(String productText) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String xpath = String.format(ACTIVE_PRODUCT_XPATH, productText);
        endpoint.jsClick(() -> xpath, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> xpath, Lookup.XPATH);
        return null;
    }

    @Click(SEARCH_BUTTON)
    HLO001_S001_ClientSearchPage clickSearch();

    @Click(CLIENT_REQUESTS)
    BAL006_S002_ClientRequestPage selectFromListOfRequests();

    @CustomAction
    default FIN001_S001_FinancialIncomeSummaryPage openIncomeModule() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> FINANCE_INFORMATION);
        endpoint.click(() -> INCOME_MODULE);
        return null;
    }

    @CustomAction
    default HPO039_S001_MbcDetailPage clickMbcDetail() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> MBC_XPATH_LABEL, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> MBC_XPATH_LABEL, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO022_S001_BusinessKontokorentPage clickKontokorentDetail() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> KONTOKORENT_XPATH_LABEL, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> KONTOKORENT_XPATH_LABEL, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO003_FlexikreditDetailPage clickFlexikredit() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> FLEXI_KREDIT_XPATH_SPAN, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> FLEXI_KREDIT_XPATH_SPAN, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO021_S001_ExpresBusinessDetailPage clickExpressBusinessDetail() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> FIRST_ACCOUNT_NUMBER_SPAN_XPATH, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> FIRST_ACCOUNT_NUMBER_SPAN_XPATH, Lookup.XPATH);
        return null;
    }

    @CustomAction
    default HPO021_S001_ExpresBusinessDetailPage clickExpressBusinessDetail(String accountNumber) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String xpath = String.format(ACCOUNT_NUMBER_SPAN_XPATH, accountNumber);
        endpoint.click(() -> xpath, Lookup.XPATH);
        endpoint.jsDoubleClick(() -> xpath, Lookup.XPATH);
        return null;
    }

    @CheckElementContent(value = INSURANCE_PRODUCT_XPATH, by = Lookup.XPATH)
    HKO101_S001_MainClientPage checkInsuranceProduct(String insuranceProduct);

    @Click(LOG_BUTTON)
    @AcceptAlert(waitSecondsForAlert = 3)
    HKO101_S001_MainClientPage clickLog();

    @CustomAction
    default HKO101_S001_MainClientPage verifyLogDataNotEmpty() {
        UfoEndpoint endpoint = this.getEndpoint(UfoEndpoint.class);
        endpoint.waitForElementsToLoad(5, Lookup.ID, Until.VISIBLE, COPY_LOG_BUTTON);
        Assertions.assertNotEquals("", endpoint.getAttribute(LOG_DATA_TEXTAREA, Lookup.XPATH, "value"));
        return null;
    }

    @Click(COPY_LOG_BUTTON)
    @AcceptAlert(waitSecondsForAlert = 3, expectedAlertText = "Chyba zkopírována do schránky. Pro vložení použijte Ctrl+V.")
    HKO101_S001_MainClientPage clickCopyLog();

    @CustomAction
    default HKO101_S001_MainClientPage storeCardLastFourDigits() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String maskedCardNumber = endpoint.getText(DEBIT_CARD_XPATH, Lookup.XPATH);
        String lastFourDigits = StringUtils.right(maskedCardNumber, 4);
        storeGlobal("LAST_FOUR_DIGITS", lastFourDigits);
        return null;
    }
}