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

import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.web.Click;
import cz.moneta.test.harness.support.web.CustomAction;
import cz.moneta.test.harness.support.web.Lookup;
import cz.moneta.test.harness.support.web.Select;
import cz.moneta.test.harness.support.web.TypeInto;
import cz.moneta.test.harness.support.web.Until;
import cz.moneta.test.harness.support.web.Wait;
import cz.moneta.test.harness.support.web.WebFlow;

import java.time.LocalDate;

import static cz.moneta.test.dsl.ufo.banka.pages.insurance.PIP001_S001_ChooseInsurancePage.CHOOSE_INSURANCE;
import static cz.moneta.test.dsl.ufo.banka.pages.insurance.PIP001_S001_ChooseInsurancePage.PIP001_S001_PAGE_LABEL_XPATH;
import static cz.moneta.test.dsl.ufo.operations.shared.SharedElements.LOAD_IMG_DIV_CLASS;

@Wait(value = PIP001_S001_PAGE_LABEL_XPATH, by = Lookup.XPATH)
@Wait(value = CHOOSE_INSURANCE, waitSecondsForElement = 30)
public interface PIP001_S001_ChooseInsurancePage extends WebFlow<PIP001_S001_ChooseInsurancePage>, StoreAccessor {

    String PIP001_S001_PAGE_LABEL_XPATH = "//div[text()='PIP001_S001']";
    String CHOOSE_INSURANCE = "PIP001_S001_C002";
    String CHOOSE_ACCOUNT = "PIP001_S001_C001";
    String CONTINUE_BUTTON = "PIP001_S001_B002";
    String FIRST_NAME_INPUT = "PIP001_S001_E007";
    String LAST_NAME_INPUT = "PIP001_S001_E009";
    String RC_INPUT = "PIP001_S001_E004";
    String DAY_OF_BIRTH_INPUT = "PIP001_S001_E010";
    String CHECKBOX_PARENT = "PIP001_S001_H001_ROD";
    String DATE_FROM_INPUT = "PIP001_S001_E001";
    String DATE_UNTIL_INPUT = "PIP001_S001_E002";
    String CALENDAR_FROM_DIV = "PIP001_S001_L005";
    String CALENDAR_UNTIL_DIV = "PIP001_S001_L007";
    String CALENDAR_DAY_GENERAL_XPATH = "//div[@id='%s']//ancestor::tbody//td[contains(@class,'ufo-static-calendar') and contains(text(), '%s')]";
    String CALENDAR_NEXT_MONTH_GENERAL_XPATH = "//div[@id='%s']//ancestor::tbody//button[contains(@class,'ufo-static-calendar-month-next')]";
    String INSURANCE_PRICE_DIV = "PIP001_S001_L009";
    String INSURANCE_FOR_INDIVIDUALS_RADIO = "PIP001_S001_R001_7735003";

    @CustomAction
    default PIP001_S001_ChooseInsurancePage fillDateFrom(LocalDate dateFrom) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String dayInCalendar = String.format(CALENDAR_DAY_GENERAL_XPATH, CALENDAR_FROM_DIV, dateFrom.getDayOfMonth());
        String nextMonthPath = String.format(CALENDAR_NEXT_MONTH_GENERAL_XPATH, CALENDAR_FROM_DIV);

        endpoint.type(() -> DATE_FROM_INPUT, "", false);
        endpoint.waitForElementsToLoad(10, Lookup.XPATH, dayInCalendar);
        if (LocalDate.now().getMonthValue() != dateFrom.getMonthValue()) {
            endpoint.click(() -> nextMonthPath, Lookup.XPATH);
        }
        endpoint.click(() -> dayInCalendar, Lookup.XPATH);
        endpoint.sleepSeconds(1); //Javascript error exception fix
        endpoint.waitForElementsToLoad(10, Lookup.XPATH, Until.GONE, dayInCalendar);
        return null;
    }

    @CustomAction
    default PIP001_S001_ChooseInsurancePage fillDateUntil(LocalDate dateUntil) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        String dayInCalendar = String.format(CALENDAR_DAY_GENERAL_XPATH, CALENDAR_UNTIL_DIV, dateUntil.getDayOfMonth());
        String nextMonthPath = String.format(CALENDAR_NEXT_MONTH_GENERAL_XPATH, CALENDAR_UNTIL_DIV);

        endpoint.type(() -> DATE_UNTIL_INPUT, "", false);
        endpoint.waitForElementsToLoad(10, Lookup.XPATH, dayInCalendar);
        if (LocalDate.now().getMonthValue() != dateUntil.getMonthValue()) {
            endpoint.click(() -> nextMonthPath, Lookup.XPATH);
        }
        endpoint.click(() -> dayInCalendar, Lookup.XPATH);
        endpoint.sleepSeconds(1); //Javascript error exception fix
        endpoint.waitForElementsToLoad(10, Lookup.XPATH, Until.GONE, dayInCalendar);
        return null;
    }

    @Wait(INSURANCE_PRICE_DIV)
    PIP001_S001_ChooseInsurancePage waitUntilPriceIsCalculated();

    @TypeInto(FIRST_NAME_INPUT)
    PIP001_S001_ChooseInsurancePage fillGivenName(String givenName);

    @TypeInto(LAST_NAME_INPUT)
    PIP001_S001_ChooseInsurancePage fillFamilyName(String familyName);

    @TypeInto(RC_INPUT)
    PIP001_S001_ChooseInsurancePage fillRc(String rc);

    @TypeInto(DAY_OF_BIRTH_INPUT)
    PIP001_S001_ChooseInsurancePage fillDayOfBirth(String dayOfBirth);

    @Click(CHECKBOX_PARENT)
    PIP001_S001_ChooseInsurancePage clickCheckBox();

    @Select(value = CHOOSE_INSURANCE, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    PIP001_S001_ChooseInsurancePage selectInsurance(String product);

    @Click(value = INSURANCE_FOR_INDIVIDUALS_RADIO, jsClick = true, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    PIP001_S001_ChooseInsurancePage clickInsuranceForIndividuals();

    @Wait(value = LOAD_IMG_DIV_CLASS, until = Until.GONE, by = Lookup.CLASSNAME)
    @Select(CHOOSE_ACCOUNT)
    PIP001_S001_ChooseInsurancePage selectAccount(String account);

    @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE)
    PIP001_S001_ChooseInsurancePage waitUntilLoaderIsGone();

    @Click(CONTINUE_BUTTON)
    PIP001_S001_ChooseInsurancePageTransitions clickContinue();

}