package com.atlassian.webdriver.bitbucket.element;

import com.atlassian.pageobjects.PageBinder;
import com.atlassian.pageobjects.elements.PageElement;
import com.atlassian.pageobjects.elements.PageElementFinder;
import com.atlassian.pageobjects.elements.query.Conditions;
import com.atlassian.pageobjects.elements.query.Poller;
import com.atlassian.pageobjects.elements.query.TimedCondition;
import com.atlassian.pageobjects.elements.query.TimedQuery;
import org.openqa.selenium.By;

import javax.inject.Inject;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;

public class SearchableSelector {

    @Inject
    private PageBinder pageBinder;

    @Inject
    private PageElementFinder elementFinder;

    private PageElement trigger;
    private By dialogLocator;
    private PageElement inputField;    // When branch selector is used in forms

    public SearchableSelector(PageElement trigger, By dialogLocator) {
        this(trigger, dialogLocator, null);
    }

    public SearchableSelector(PageElement trigger, By dialogLocator, PageElement inputField) {
        this.trigger = checkNotNull(trigger, "trigger");
        this.dialogLocator = checkNotNull(dialogLocator, "dialogLocator");
        this.inputField = inputField;
    }

    public SearchableSelectorDialog open() {
        trigger.click();
        SearchableSelectorDialog searchableSelectorDialog = getDialog();
        Poller.waitUntilTrue(searchableSelectorDialog.isOpen());
        Poller.waitUntilFalse(searchableSelectorDialog.isLoadingPage());
        return searchableSelectorDialog;
    }

    public TimedQuery<String> getSelectedValue() {
        return getValueInput().timed().getValue();
    }

    public String getTriggerText() {
        return trigger.getText();
    }

    public String getSelectedItemName() {
        return trigger.find(By.className("name")).getText();
    }

    public TimedCondition hasValue() {
        return Conditions.forMatcher(getSelectedValue(), not(isEmptyOrNullString()));
    }

    private SearchableSelectorDialog getDialog() {
        return pageBinder.bind(SearchableSelectorDialog.class, elementFinder.find(dialogLocator));
    }

    private PageElement getValueInput() {
        checkNotNull(inputField, "Input field must be provided to get the value input");
        return inputField;
    }
}
