package cz.moneta.test.dsl.ufo.operations.ufoOperations;

import cz.moneta.test.dsl.ufo.operations.shared.SharedElements;
import cz.moneta.test.dsl.ufo.operations.shared.topmenu.XXX701_SharedTopMenu;
import cz.moneta.test.dsl.ufo.operations.ufoOperations.taskslist.StateOfTaskFilter;
import cz.moneta.test.dsl.ufo.operations.ufoOperations.taskslist.TypesOfViewFilter;
import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.ufo.UfoEndpoint;
import cz.moneta.test.harness.support.web.*;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;

import java.util.List;

import static cz.moneta.test.dsl.ufo.operations.shared.SharedElements.LOAD_IMG_DIV_CLASS;
import static cz.moneta.test.dsl.ufo.operations.ufoOperations.UKO720_S001_TaskList.CLIENT_SEARCH_BY_RC_FIELD;

@Wait(value = CLIENT_SEARCH_BY_RC_FIELD, until = Until.VISIBLE)
@Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE, waitSecondsForElement = 80)
public interface UKO720_S001_TaskList extends WebFlow<UKO720_S001_TaskList>, XXX701_SharedTopMenu<UKO720_S001_TaskList>, StoreAccessor {

    String TASK_ID_KEY = "TASK_ID";
    String SECOND_TASK_ID_KEY = "SECOND_TASK_ID";
    String CLIENT_SEARCH_BY_RC_FIELD = "UKO720_S001_E023";
    String FIRST_TASK_CLIENT_RC = "UKO720_S001_L131-1";
    String OBJECT_SEARCH_BY_ID_FIELD = "UKO720_S001_E010";
    String FIRST_TASK_OBJECT_ID = "UKO720_S001_L171-1";
    String DEPARTMENTS_CHECKBOX = "UKO720_S001_H008_1";
    String FIND_BUTTON = "UKO720_S001_B001";
    String RESET_BUTTON = "UKO720_S001_B002";
    String TYPE_OF_VIEW_MENU = "UKO720_S001_C006";
    String TASK_ID_INPUT = "UKO720_S001_E007";
    String NEW_MAIN_TASK = "//button[contains(@title, 'UKO720_S001_I002')]";
    String NEW_QUICK_TASK = "//button[contains(@title, 'UKO720_S001_I015')]";
    String ADMINISTRATIONS_XPATH = "//button[contains(@title, 'UKO720_S001_I004')]";
    String DOUBLE_DART_BUTTON = "UKO720_S001_I001_innerTab";
    String FIRST_TASK_DETAIL = "UKO720_S001_P001-1";
    String REVITALIZATION_BUTTON = "UKO720_S001_P049-1";
    String MFCH_DETAIL = "//tr[.//*[contains(text(),'Kontrola totožnosti')]]/preceding-sibling::tr//img[contains(@id,'UKO720_S001_P001')]";
    String FIRST_RECORD_TASK_ID_LABEL = "UKO720_S001_L005-1";
    String FIRST_TASK_STATUS = "UKO720_S001_L019-1";
    String FIRST_TASK_TASKMASTER = "UKO720_S001_L032-1";
    String THIRD_PAGE_LABEL = "PAG501_S001_L003";
    String LOADER_POPUP = "gwt-PopupPanel";
    String FIRST_RECORD_TASK_ID_XPATH = "//div[@id='UKO720_S001_L005-1' and text()='%s']";
    String FIRST_NAME_OF_TASK = "UKO720_S001_L014-1";
    String INCLUDING_LOCKED_CHECKBOX = "UKO720_S001_H004_1";
    String FIRST_STATE_OF_TASK = "UKO720_S001_G002-0";
    String DEPARTMENT_FILTER_NAME_DYNAMIC = "UKO720_S001_G001-%s";
    String FIRST_TYPE_OF_TASK = "UKO720_S001_G004-0";
    String FILTER_BUTTON = "UKO720_S001_B011";
    String SSO_SOLVER_SEARCH = "UKO720_S001_E005";
    String SSO_SUBMITTER_SEARCH = "UKO720_S001_E006";
    String PRIORITY_SEARCH_COMBOBOX = "UKO720_S001_C002";
    String BUSSINES_SEARCH_COMBOBOX = "UKO720_S001_C003";
    String CLIENT_SEARCH_BY_ICO_NUMBER = "UKO720_S001_E022";
    String ID_OF_CLIENT_SEARCH = "UKO720_S001_E009";
    String EXPAND_FILTER_ARROW = "UKO720_S001_P004";
    String COLLAPSE_FILTER_ARROW = "UKO720_S001_P003";

    @CustomAction
    default UKO720_S001_TaskList saveTaskID() {
        UfoEndpoint endpoint = this.getEndpoint(UfoEndpoint.class);
        String establishedTaskText = endpoint.getText(STATUS_LABEL).replaceAll(".*(T_\\d+) .*", "$1");
        this.store(TASK_ID_KEY, establishedTaskText);
        return null;
    }

    @CustomAction
    default UKO720_S001_TaskList saveSecondTaskID() {
        UfoEndpoint endpoint = this.getEndpoint(UfoEndpoint.class);
        String establishedTaskText = endpoint.getText(STATUS_LABEL).replaceAll(".*(T_\\d+) .*", "$1");
        this.store(SECOND_TASK_ID_KEY, establishedTaskText);
        return null;
    }

    @Wait(value = FIRST_TASK_DETAIL, until = Until.CLICKABLE)
    @Click(value = FIRST_TASK_DETAIL, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskPage clickOpenTaskDetail();

    @CustomAction
    default UKO720_S001_TaskList clickRevitalization() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> REVITALIZATION_BUTTON);
        if (endpoint.getAlertText(10).equals("Důvod oživení")) {
            endpoint.acceptAlert(1);
        }
        endpoint.waitForElementsToLoad(5, Lookup.CLASSNAME, Until.GONE, LOAD_IMG_DIV_CLASS);
        return null;
    }

    @CheckElementPresent(REVITALIZATION_BUTTON)
    UKO720_S001_TaskList checkRevitalizationButtonPresent();

    @Click(value = MFCH_DETAIL, by = Lookup.XPATH)
    UKO720_S001_TaskDetail clickMFCHDetail();

    @Click(DOUBLE_DART_BUTTON)
    UKO720_S001_TaskList clickDoubleDartButton();

    @Click(value = NEW_MAIN_TASK, by = Lookup.XPATH, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskPage clickNewMainTask();

    @Click(value = NEW_QUICK_TASK, by = Lookup.XPATH, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_QuickTaskPage clickNewQuickTask();

    @Click(value = ADMINISTRATIONS_XPATH, by = Lookup.XPATH)
    UKO729_S001_AdministrationPage clickAdministration();

    @Wait(value = CLIENT_SEARCH_BY_RC_FIELD, until = Until.VISIBLE)
    @TypeInto(CLIENT_SEARCH_BY_RC_FIELD)
    UKO720_S001_TaskList fillBirthNumber(String birthNumber);

    @Wait(value = OBJECT_SEARCH_BY_ID_FIELD, until = Until.VISIBLE)
    @TypeInto(OBJECT_SEARCH_BY_ID_FIELD)
    UKO720_S001_TaskList fillIdObject(String idObject);

    @CheckElementContent(FIRST_TASK_CLIENT_RC)
    UKO720_S001_TaskList assertTaskClientRc(String birthNumber);

    @CheckElementContent(FIRST_TASK_OBJECT_ID)
    UKO720_S001_TaskList assertTaskObjectId(String objectId);

    @Click(DEPARTMENTS_CHECKBOX)
    UKO720_S001_TaskList clickDepartments();

    @Click(value = FILTER_BUTTON, andWait = @Wait(value = LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskList clickFilter();

    @Wait(value = FIND_BUTTON, until = Until.VISIBLE)
    @Click(value = FIND_BUTTON, andWait = @Wait(value = SharedElements.LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskList clickFind();

    @Wait(value = RESET_BUTTON, until = Until.VISIBLE)
    @Click(value = RESET_BUTTON, andWait = @Wait(value = SharedElements.LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskList clickReset();

    @Click(value = FIND_BUTTON, andWait = @Wait(FIRST_TASK_DETAIL))
    @Click(FIRST_TASK_DETAIL)
    UKO720_S001_TaskList clickFindAndSelectFirst();

    @Select(value = TYPE_OF_VIEW_MENU, andWait = @Wait(value = SharedElements.LOAD_IMG_DIV_CLASS, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskList selectTypeOfView(TypesOfViewFilter typeOfView);

    @TypeInto(TASK_ID_INPUT)
    UKO720_S001_TaskList fillTaskID(String taskID);

    @Click(FIRST_TASK_DETAIL)
    UKO720_S001_TaskDetail clickToFirstTask();

    @CustomAction
    default UKO720_S001_TaskList waitUntilFoundMFCHTask() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        for (int i = 20; i >= 0; i--) { // max 2 minuty
            endpoint.click(() -> FIND_BUTTON);
            endpoint.waitForElementsToLoad(10, Lookup.CLASSNAME, Until.GONE, LOAD_IMG_DIV_CLASS);
            if (endpoint.isElementPresent(MFCH_DETAIL, Lookup.XPATH)) {
                break;
            }
            if (i == 0) {
                Assert.fail("Timeout occurred while finding a Manual Fraud Check Task");
            }
            endpoint.sleepSeconds(6);
        }
        return null;
    }

    @StoreElementContent(storeKey = TASK_ID_KEY, value = FIRST_RECORD_TASK_ID_LABEL, by = Lookup.ID)
    UKO720_S001_TaskList storeFirstRecordTaskId();

    @Wait(value = FIRST_TASK_STATUS, until = Until.VISIBLE)
    @CheckElementContent(FIRST_TASK_STATUS)
    UKO720_S001_TaskList assertTaskStatus(String status);

    @CheckElementContent(FIRST_TASK_TASKMASTER)
    UKO720_S001_TaskList assertTaskTaskmaster(String researcher);

    @Click(value = THIRD_PAGE_LABEL, andWait = @Wait(value = LOADER_POPUP, by = Lookup.CLASSNAME, until = Until.GONE))
    UKO720_S001_TaskList clickThirdPage();

    @CustomAction
    default UKO720_S001_TaskList checkFirstRecordTaskIdChanged() {
        UfoEndpoint endpoint = this.getEndpoint(UfoEndpoint.class);
        String firstRecordTaskIdElement = String.format(FIRST_RECORD_TASK_ID_XPATH, this.get(TASK_ID_KEY).toString());
        endpoint.waitForElementsToLoad(3, Lookup.XPATH, Until.GONE, firstRecordTaskIdElement);
        Assertions.assertNotEquals(this.get(TASK_ID_KEY), endpoint.getText(FIRST_RECORD_TASK_ID_LABEL));
        Assertions.assertNotEquals("", endpoint.getText(FIRST_RECORD_TASK_ID_LABEL));
        return null;
    }

    @CheckElementPresent(FIRST_NAME_OF_TASK)
    UKO720_S001_TaskList checkPresentOfFirstTask();

    @CustomAction
    default UKO720_S001_TaskList checkStatesOfTaskFilterValues(boolean checkIfChecked, List<StateOfTaskFilter> statesShouldPresent) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        for (StateOfTaskFilter state : statesShouldPresent) {
            if (checkIfChecked)
                Assertions.assertEquals("true", endpoint.getAttribute(state.getElementXpath(), Lookup.XPATH, "checked"), String.format("The filter of task state %s isn't checked.", state.name()));
            else
                Assertions.assertTrue(endpoint.isElementVisible(state.getElementXpath(), Lookup.XPATH), String.format("The filter of task state %s isn't visible.", state.name()));
        }
        return null;
    }

    @CheckElementPresent(INCLUDING_LOCKED_CHECKBOX)
    UKO720_S001_TaskList checkIncludingLockedCheckbox();

    @CustomAction
    default UKO720_S001_TaskList checkDataFiltering(String index) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.click(() -> String.format(DEPARTMENT_FILTER_NAME_DYNAMIC, index));
        endpoint.waitForElementsToLoad(5, Until.CLICKABLE, FILTER_BUTTON);
        endpoint.click(() -> FILTER_BUTTON);
        endpoint.click(() -> FIRST_TYPE_OF_TASK);
        Assertions.assertEquals("true", endpoint.getAttribute(FIRST_TYPE_OF_TASK, "checked"), "The checkbox of first type of task isn't checked.");
        return null;
    }

    @Click(value = DEPARTMENT_FILTER_NAME_DYNAMIC, isStringDynamicXpath = true)
    UKO720_S001_TaskList clickDepartmentFilterNameDynamic(String index);

    @CustomAction
    default UKO720_S001_TaskList checkSearchOptionsEnabled() {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        List<String> elementsForCheck = List.of(SSO_SOLVER_SEARCH, SSO_SUBMITTER_SEARCH, PRIORITY_SEARCH_COMBOBOX, BUSSINES_SEARCH_COMBOBOX, TASK_ID_INPUT, CLIENT_SEARCH_BY_RC_FIELD, CLIENT_SEARCH_BY_ICO_NUMBER, ID_OF_CLIENT_SEARCH, OBJECT_SEARCH_BY_ID_FIELD);
        for (String element : elementsForCheck) {
            Assertions.assertTrue(endpoint.isElementEnabled(element), "Element " + element + " isn't enabled");
        }
        return null;
    }

    @CustomAction
    default UKO720_S001_TaskList typeIntoSsoSolver(String sso) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        Assertions.assertNull(endpoint.getAttribute(SSO_SOLVER_SEARCH, "readonly"), "Element " + SSO_SOLVER_SEARCH + " is read only.");
        endpoint.type(() -> SSO_SOLVER_SEARCH, sso, false);
        return null;
    }

    @CustomAction
    default UKO720_S001_TaskList typeIntoSsoSubmitter(String sso) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        Assertions.assertNull(endpoint.getAttribute(SSO_SUBMITTER_SEARCH, "readonly"), "Element " + SSO_SUBMITTER_SEARCH + " is read only.");
        endpoint.type(() -> SSO_SUBMITTER_SEARCH, sso, false);
        return null;
    }

    @Wait(value = EXPAND_FILTER_ARROW, until = Until.CLICKABLE)
    @Click(EXPAND_FILTER_ARROW)
    UKO720_S001_TaskList clickExpandFilterArrow();

    @Wait(value = COLLAPSE_FILTER_ARROW, until = Until.CLICKABLE)
    @Click(COLLAPSE_FILTER_ARROW)
    UKO720_S001_TaskList clickCollapseFilterArrow();

    @CustomAction
    default UKO720_S001_TaskList checkFirstStateOfTasksByViewType(TypesOfViewFilter viewType, StateOfTaskFilter stateOfTask) {
        UfoEndpoint endpoint = getEndpoint(UfoEndpoint.class);
        endpoint.selectByVisibleText(TYPE_OF_VIEW_MENU, viewType.getUfoValue());
        endpoint.waitForElementsToLoad(10, Lookup.CLASSNAME, Until.GONE, LOAD_IMG_DIV_CLASS);
        Assertions.assertEquals(stateOfTask.getValue(), endpoint.getAttribute(FIRST_STATE_OF_TASK, "value"), "The first state of task in the filter doesn't match the selected view type.");
        return null;
    }

}