package cz.moneta.test.dsl.hypos.pages.contract.realty;

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.harness.endpoints.hypos.HyposEndpoint;
import cz.moneta.test.harness.support.web.*;

import static cz.moneta.test.dsl.hypos.pages.contract.realty.UnitDetailPage.PAGE_TITLE;
import static cz.moneta.test.dsl.hypos.pages.contract.realty.UnitDetailPage.APPROVED_SUPERVISION_BUTTON;

@Wait(value = {PAGE_TITLE, APPROVED_SUPERVISION_BUTTON}, waitSecondsForElement = 120)
public interface UnitDetailPage extends HyposPageFlow<UnitDetailPage>, Menu {
    String PAGE_TITLE = "//h2[text()='Detail celku']";
    String APPROVED_SUPERVISION_BUTTON = "//a[contains(text(),'schválenou supervizi')]";
    String ADD_UNIT_BUTTON = "//a[contains(text(),'přidat jednotku')]";
    String UNIT_CATEGORY_SELECT = "//select[@id='cmd']";
    String CADASTRAL_TERRITORY_INPUT = "//input[@id='nazev-katuz']";
    String DOCUMENT_NUMBER_INPUT = "//input[@id='cislo-pd']";
    String LAND_NUMBER_INPUT = "//input[@name='lot_no']";
    String CADASTRAL_TERRITORY_AUTOSUGGEST = "//a[contains(text(),'%s')]";
    String SUBMIT_BUTTON = "//input[@value='Vyhledat']";
    String USED_PLEDGE_INPUT = "//input[@name='dummy']";
    String USED_PLEDGE_LINK = "//input[@name='dummy']/following-sibling::a";
    String CHECKED_PLEDGE_INPUT = "//input[@name='share[]' and @checked='checked']";
    String UNUSED_PLEDGE_INPUT = "//input[@name='share[]']";
    String ADD_TABLE_TH = "//*[contains(text(),'Podíly zástavců v celku')]";
    String SAVE_UNIT_BUTTON = "//a[contains(text(),'Uložit')]";
    String REMOVE_BUTTON = "//td[contains(text(),'%1$s')]/following-sibling::td[%2$s]/ul/li/a[contains(text(),'odebrat')]";
    String ADD_BUTTON = "//td[contains(text(),'%s')]/following-sibling::td[contains(@class,'operations')]/a[contains(text(),'přidat')]";
    String NO_FLATS_TD = "//td[contains(text(),'celek neobsahuje žádné byty')]";
    String NO_HOUSES_TD = "//td[contains(text(),'celek neobsahuje žádné budovy')]";
    String NO_LANDS_TD = "//td[contains(text(),'celek neobsahuje žádné pozemky')]";
    String ORDER_VALUATION_BUTTON = "//span/a[contains(text(),'tržní ocenění')]";
    String ORDER_SUPERVISION_BUTTON = "//span/a[contains(text(),'supervizi')]";
    String FIRST_ORDER_BUTTON = "//tr[@class='tooltip']/td[1]/a[1]";
    String UNIT_REMOVE_BUTTON = "//td[text()='%s']//following::a[contains(@href,'unit.attach-form')]";
    String CONTRACT_ID_LINK = "//th[contains(text(),'Seznam obchodů')]/ancestor::table//a[contains(@href,'sec.overview')]";

    String CONTRACT_ID = "CONTRACT_ID";

    @Click(FIRST_ORDER_BUTTON)
    ValuationDetailPage openFirstOrder();

    @Click(ORDER_VALUATION_BUTTON)
    OrderValuationPage clickOnOrderValuation();

    @Click(ORDER_SUPERVISION_BUTTON)
    OrderSupervisionPage clickOnOrderSupervision();

    @Click(APPROVED_SUPERVISION_BUTTON)
    AcquireApprovedSupervisionPage clickApprovedSupervisionLink();

    @Wait(value = ADD_UNIT_BUTTON, waitSecondsForElement = 5)
    @Click(ADD_UNIT_BUTTON)
    UnitDetailPage clickAddUnit();

    @TypeInto(UNIT_CATEGORY_SELECT)
    @KeyPress(Key.ENTER)
    UnitDetailPage selectUnitCategory(String unitCategory);

    @TypeInto(CADASTRAL_TERRITORY_INPUT)
    UnitDetailPage fillCadastralTerritory(String cadastralTerritory);

    @Click(value = CADASTRAL_TERRITORY_AUTOSUGGEST, isStringDynamicXpath = true)
    UnitDetailPage clickAutosuggestLink(String cadastralTerritory);

    @TypeInto(DOCUMENT_NUMBER_INPUT)
    UnitDetailPage fillDocumentNumber(String documentNumber);

    @TypeInto(LAND_NUMBER_INPUT)
    UnitDetailPage fillLandNumber(String landNumber);

    @Click(SUBMIT_BUTTON)
    UnitDetailPage clickSubmit();

    @CustomAction
    default UnitDetailPage clickRemove(String orientationNumber, String tdPosition) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.click(() -> String.format(REMOVE_BUTTON, orientationNumber, tdPosition));
        return null;
    }

    @CustomAction
    default UnitDetailPage clickAdd(String orientationNumber) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.click(() -> String.format(ADD_BUTTON, orientationNumber));
        return null;
    }

    @CustomAction
    default UnitDetailPage addUnit(String orientationNumber) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        clickAdd(orientationNumber);
        endpoint.click(() -> UNUSED_PLEDGE_INPUT);
        endpoint.click(() -> SAVE_UNIT_BUTTON);
        return null;
    }

    /**
     * Checker, if unit is used in other realty, if so, it is removed to it could be used elsewhere.
     *
     * @param orientationNumber - String of property orientation number
     * @param tdPosition        - possition of button in HTML structure... Flats has different td than houses.
     * @return
     */
    @CustomAction
    default UnitDetailPage checkUnitUsage(String orientationNumber, String tdPosition) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        clickAdd(orientationNumber);
        endpoint.waitForElementsToLoad(5, ADD_TABLE_TH);

        if (endpoint.isElementPresent(USED_PLEDGE_INPUT, Lookup.XPATH)) {
            removeUnit(orientationNumber, tdPosition);
            log("Unit removed.");
        } else {
            log("Unit is available to add to the new realty.");
        }
        return null;
    }

    /**
     * Redirection to another url. In this case it is used for redirect back to created realty detail.
     *
     * @param url - String Url of realty detail.
     * @return
     */
    @CustomAction
    default UnitDetailPage navigateTo(String url) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.changeUrl(url);
        return null;
    }

    /**
     * Remove unit from other realty.
     *
     * @param orientationNumber - String of property orientation number
     * @param tdPosition        - possition of button in HTML structure... Flats has different td than houses.
     * @return
     */
    @CustomAction
    default UnitDetailPage removeUnit(String orientationNumber, String tdPosition) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        log("Unit is used elsewhere, removing it first.");
        endpoint.click(() -> USED_PLEDGE_LINK);

        clickRemove(orientationNumber, tdPosition);
        endpoint.click(() -> CHECKED_PLEDGE_INPUT);
        endpoint.click(() -> SAVE_UNIT_BUTTON);
        endpoint.waitForElementsToLoad(30, NO_FLATS_TD);
        endpoint.waitForElementsToLoad(30, NO_HOUSES_TD);
        endpoint.waitForElementsToLoad(30, NO_LANDS_TD);
        return null;
    }

    @CustomAction
    default UnitDetailPage removeUnit(String number) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.click(() -> String.format(UNIT_REMOVE_BUTTON, number));
        endpoint.click(() -> CHECKED_PLEDGE_INPUT);
        endpoint.click(() -> SAVE_UNIT_BUTTON);
        return null;
    }

    @CustomAction
    default UnitDetailPage getContractId(Harness harness) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        harness.store(CONTRACT_ID, endpoint.getText(CONTRACT_ID_LINK));
        return null;
    }
}