package cz.moneta.test.dsl.hypos.pages.hypokalkulacka;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.hypos.components.Menu;
import cz.moneta.test.dsl.hypos.pages.HyposPageFlow;
import cz.moneta.test.dsl.hypos.pages.contract.ContractHistoryPage;
import cz.moneta.test.dsl.util.data.hypos.HyposContract;
import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.hypos.HyposEndpoint;
import cz.moneta.test.harness.support.web.*;
import org.junit.jupiter.api.Assertions;

import static cz.moneta.test.dsl.hypos.enums.Client.FIRST_CLIENT;
import static cz.moneta.test.dsl.hypos.pages.hypokalkulacka.HypokalkulackaPage.ADD_CLIENT_BUTTON;
import static cz.moneta.test.dsl.hypos.pages.hypokalkulacka.HypokalkulackaPage.HYPOKALKULACKA_LOADER;

@Wait(ADD_CLIENT_BUTTON)
@Wait(value = HYPOKALKULACKA_LOADER, until = Until.GONE)
public interface HypokalkulackaPage extends HyposPageFlow<HypokalkulackaPage>, Menu, StoreAccessor {
    String HYPOKALKULACKA_VERSION_SELECT = "//select[@id='versions']";
    String HYPOKALKULACKA_LATEST_VERSION = HYPOKALKULACKA_VERSION_SELECT + "/option[@class='latest']";
    String ADD_CLIENT_BUTTON = "//div[@id='col-client']//a[@id='butt-new-client']";
    String ADD_PERMANENT_ADDRESS_BUTTON = "//div[@id='col-client']//a[contains(@class,'permanent-address') and text()='Zadat']";
    String ADD_INCOME_BUTTON = "(//table[contains(@class,'income')]//a[contains(@class,'income-fullname')])[%s]";
    String ADD_EXPENDITURE_BUTTON = "(//table[contains(@class,'expenditure')]//td[contains(@class,'expenditure-fullname')]/a[not(contains(@class, 'no-name'))])[%s]";
    String ADD_HOUSEHOLD_INCOME_BUTTON = "(//table[contains(@class,'household')]//a[@class='household-edit'])[%s]";
    String ADD_REALTY_BUTTON = "//div[@id='col-section']//a[@id='butt-new-realty']";
    String EDIT_LOAN_BUTTON = "//div[@id='col-loan']//a[@id='butt-edit-loan']";
    String EDIT_APPLICATION_BUTTON = "//div[@id='col-loan']//a[@id='butt-edit-application']";
    String FIRST_EXPECTED_DRAW_DATE_INPUT = "//input[@id='first-expected-draw-date']";
    String CALCULATE_BUTTON = "//div[@id='col-calculation']//a[@id='butt-calculate'] ";
    String EXPENDITURE_TABLE = "//span[text()='Výdaje klientů']//following::table[1][not(contains(@style,'display: none'))]";

    String DOCUMENTS_DIV = "//div[@id='col-docs']";
    String GENERATE_AGREEMENTS101_BUTTON = DOCUMENTS_DIV + "//span[@id='generate-link-186']/a";
    String GENERATE_AGREEMENTS101_LOADER_IMG = DOCUMENTS_DIV + "//span[@id='generate-link-186']/img[@src='/img/common/loadingAnimationSmall.gif']";
    String SIGN_AGREEMENTS101_BUTTON = DOCUMENTS_DIV + "//span[@id='sign-link-186']/a";
    String GENERATE_APPLICATION_BUTTON = DOCUMENTS_DIV + "//span[@id='generate-link-333']/a[not(contains(@class,'generate-disabled'))]";
    String GENERATE_APPLICATION_LOADER_IMG = DOCUMENTS_DIV + "//span[@id='generate-link-333']/img[@src='/img/common/loadingAnimationSmall.gif']";
    String SIGN_APPLICATION_BUTTON = DOCUMENTS_DIV + "//span[@id='sign-link-333']/a";

    String SAVE_HYPOKALKULACKA_BUTTON_SPAN = "//span[@id='save-version' and not(contains(@style,'display: none'))]";
    String SAVE_HYPOKALKULACKA_BUTTON = SAVE_HYPOKALKULACKA_BUTTON_SPAN + "/input[@value='Uložit']";
    String SAVE_NEW_HYPOKALKULACKA_VERSION_BUTTON = SAVE_HYPOKALKULACKA_BUTTON_SPAN + "/input[@value='Uložit novou verzi']";

    String HYPOKALKULACKA_CALCULATE_LOADER = "//div[@id='col-calculation-container']//div[@class='loading-overlay']";
    String HYPOKALKULACKA_LOADER = "//body/div[@class='loading' and contains(@style,'display: block')]";


    String HYPOKALKULACKA_ID = "HYPOKALKULACKA_ID";
    String HYPOKALKULACKA_VERSION_SAVED_ALERT_TEXT = "Hypokalkulačka byla úspěšně uložena.";

    HypokalkulackaPage onHypokalkulackaPage();

    @Click(ADD_CLIENT_BUTTON)
    HypokalkulackaClientDetailPage clickAddClientButton();

    @Click(ADD_PERMANENT_ADDRESS_BUTTON)
    HypokalkulackaAddressPage clickAddPermanentAddress();

    @Click(value = ADD_INCOME_BUTTON, isStringDynamicXpath = true)
    HypokalkulackaClientIncomePage clickClientIncomeButton(String client);

    @Click(value = ADD_EXPENDITURE_BUTTON, isStringDynamicXpath = true)
    HypokalkulackaClientExpenditurePage clickClientExpenditureButton(String client);

    @Click(value = ADD_HOUSEHOLD_INCOME_BUTTON, isStringDynamicXpath = true)
    HypokalkulackaHouseholdPage clickHouseholdButton(String household);

    @Click(ADD_REALTY_BUTTON)
    HypokalkulackaRealtyPage clickAddRealtyButton();

    @Click(EDIT_LOAN_BUTTON)
    HypokalkulackaEditLoanPage clickEditLoanButton();

    @Click(EDIT_APPLICATION_BUTTON)
    HypokalkulackaLoanApplicationPage clickEditApplicationButton();

    @Click(value = CALCULATE_BUTTON, andWait = @Wait(value = HYPOKALKULACKA_CALCULATE_LOADER, until = Until.GONE))
    HypokalkulackaPage clickCalculateButton();

    @CustomAction
    default HypokalkulackaPage fillFirstExpectedDrawDate(String drawDate) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.type(() -> FIRST_EXPECTED_DRAW_DATE_INPUT, drawDate, true);
        endpoint.sendKeysOneAtATime(Key.TAB);
        endpoint.waitForElementsToLoad(20, Until.GONE, HYPOKALKULACKA_CALCULATE_LOADER);
        return null;
    }

    @Wait(value = GENERATE_AGREEMENTS101_BUTTON, waitSecondsForElement = 60, until = Until.VISIBLE)
    @Click(value = GENERATE_AGREEMENTS101_BUTTON, andWait = @Wait(value = GENERATE_AGREEMENTS101_LOADER_IMG, waitSecondsForElement = 60, until = Until.GONE))
    HypokalkulackaPage clickGenerateAgreements101();

    @CustomAction
    default HypokalkulackaDocumentSignature clickSignAgreements101() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.waitForElementsToLoad(60, Until.VISIBLE, SIGN_AGREEMENTS101_BUTTON);
        endpoint.click(() -> SIGN_AGREEMENTS101_BUTTON);
        endpoint.acceptAlert(20);
        return null;
    }

    @CustomAction
    default HypokalkulackaPage clickGenerateMortgageApplication() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.waitForElementsToLoad(60, Until.VISIBLE, GENERATE_APPLICATION_BUTTON);
        endpoint.click(() -> GENERATE_APPLICATION_BUTTON);
        endpoint.acceptAlert(20);
        endpoint.acceptAlert(60);
        endpoint.waitForElementsToLoad(60, Until.GONE, GENERATE_APPLICATION_LOADER_IMG);
        return null;
    }

    @CustomAction
    default HypokalkulackaDocumentSignature clickSignMortgageApplication() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.waitForElementsToLoad(60, Until.VISIBLE, SIGN_APPLICATION_BUTTON);
        endpoint.click(() -> SIGN_APPLICATION_BUTTON);
        endpoint.acceptAlert(20);
        return null;
    }

    @CustomAction
    default HypokalkulackaPage getHypokalkulackaVersion(Harness harness) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        harness.store(HYPOKALKULACKA_ID, endpoint.getAttribute(HYPOKALKULACKA_LATEST_VERSION, "value"));
        return null;
    }

    @CustomAction
    default HypokalkulackaPage clickSaveNewHypokalkulackaVersionAndAcceptAlertText() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.waitForElementsToLoad(30, EXPENDITURE_TABLE);
        endpoint.waitForElementsToLoad(30, Until.GONE, HYPOKALKULACKA_CALCULATE_LOADER);
        endpoint.waitForElementsToLoad(10, Until.CLICKABLE, SAVE_NEW_HYPOKALKULACKA_VERSION_BUTTON);
        endpoint.click(() -> SAVE_NEW_HYPOKALKULACKA_VERSION_BUTTON);
        String alertText = endpoint.getAlertText(60);
        Assertions.assertEquals(alertText, HYPOKALKULACKA_VERSION_SAVED_ALERT_TEXT, String.format("Alert text is not: %s", HYPOKALKULACKA_VERSION_SAVED_ALERT_TEXT));
        endpoint.acceptAlert(60);
        return null;
    }

    @CustomAction
    default HypokalkulackaPage clickSaveHypokalkulackaButtonAndCheckAlertText() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.waitForElementsToLoad(30, EXPENDITURE_TABLE);
        endpoint.waitForElementsToLoad(30, Until.GONE, HYPOKALKULACKA_CALCULATE_LOADER);
        endpoint.waitForElementsToLoad(10, Until.CLICKABLE, SAVE_HYPOKALKULACKA_BUTTON);
        endpoint.click(() -> SAVE_HYPOKALKULACKA_BUTTON);
        String alertText = endpoint.getAlertText(60);
        Assertions.assertEquals(alertText, HYPOKALKULACKA_VERSION_SAVED_ALERT_TEXT, String.format("Alert text is not: %s", HYPOKALKULACKA_VERSION_SAVED_ALERT_TEXT));
        endpoint.acceptAlert(60);
        return null;
    }

    @CustomAction
    default ContractHistoryPage closeHypokalkulackaAndContinueWithContract(HyposContract hyposContract) {
        String clientName = String.format("%s %s", hyposContract.getClients().get(FIRST_CLIENT.getValue()).getNonClient().firstName(), hyposContract.getClients().get(FIRST_CLIENT.getValue()).getNonClient().lastName());
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.closeCurrentWindow();
        endpoint.switchToWindowByTitle(clientName);
        endpoint.switchToFrame(MAIN_FRAME_XPATH);
        return null;
    }

    @CheckElementPresent(SAVE_NEW_HYPOKALKULACKA_VERSION_BUTTON)
    HypokalkulackaPage checkSaveNewHypokalkulackaVersionButtonPresent();
}