package ru.yandex.autotests.direct.web.pages.regionselectpopup;

import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

import ru.yandex.autotests.direct.web.util.DirectWebError;
import ru.yandex.qatools.htmlelements.annotations.Name;
import ru.yandex.qatools.htmlelements.element.Button;
import ru.yandex.qatools.htmlelements.element.HtmlElement;
import ru.yandex.qatools.htmlelements.element.TypifiedElement;

/**
 * Поп-ап изменения Единый регион показа для всех объявлений
 */
@FindBy(xpath = "//div[contains(@class, 'b-region-selector__popup-content')]")
@Name("Поп-ап изменения Единый регион показа для всех объявлений")
public class RegionSelectPopupBlock extends HtmlElement {
    @Name("Заголовок поп-апа")
    @FindBy(xpath = ".//div[@class = 'b-popupa__title']")
    public WebElement title;

    @Name("Кнопка 'ОК'")
    @FindBy(xpath = ".//span[contains(@class, 'b-popupa__submit')]/input[@class = 'b-form-button__input']")
    public WebElement okButton;

    @Name("Кнопка 'Выбрать'")
    @FindBy(xpath = ".//span[contains(@class, 'b-promo-spros__getregion')]/input")
    public Button selectButton;

    @Name("Кнопка 'Отмена'")
    @FindBy(xpath = ".//span[contains(@class, 'b-popupa__cancel')]/input[@class = 'b-form-button__input']")
    public WebElement cancelButton;

    @Name("Крестик закрытия поп-апа")
    @FindBy(xpath = ".//i[@class = 'b-popupa__close']")
    public WebElement closeButton;

    @Name("Список регионов с чекбоксами в 'Быстром выборе'")
    @FindBy(xpath = ".//span[contains(@class, 'b-pseudo-link b-regions-tree__quick')]")
    public List<WebElement> quickRegionList;

    @Name("Список регионов с чекбоксами")
    @FindBy(xpath = ".//div[contains(@class, 'b-regions-tree__leaf')]")
    public List<RegionSelect> regionSelectList;

    @Name("")
    @FindBy(xpath = ".//span[contains(@class, 'b-regions-tree__quick_val_clear')]")
    public WebElement clearAllRegionsLink;

    public void fillRegions(String geo) {
        if (geo == null)
            return;
        clearAllRegionsLink.click();
        selectRegions(geo);
        okButton.click();
    }

    private void selectRegions(String geo) {
        String[] regions = geo.split(",");
        for (String regionID : regions) {
            selectRegion(regionID);
        }
    }

    private void selectRegion(String regionID) {
        if (regionID.startsWith("-")) {
            expandAll(getRegionSelect(regionID.replace("-", "")));
            getRegionSelect(regionID.replace("-", "")).deselect();
        } else {
            expandAll(getRegionSelect(regionID));
            getRegionSelect(regionID).select();
        }
    }

    private LinkedList<RegionSelect> getAncestorsFor(RegionSelect regionSelect, LinkedList<RegionSelect> result) {
        if (!regionSelect.getParentRegion().equals("")) {
            RegionSelect parent = getRegionSelect(regionSelect.getParentRegion());
            result.add(parent);
            getAncestorsFor(parent, result);
        }
        return result;
    }

    private void expandAll(RegionSelect regionSelect) {
        if (!regionSelect.isDisplayed()) {
            LinkedList<RegionSelect> ancestors = getAncestorsFor(regionSelect, new LinkedList<>());
            for (int i = ancestors.size() - 1; i >= 0; i--) {
                ancestors.get(i).expand();
            }
        }
    }

    public RegionSelect getRegionSelect(String regionID) {
        WebElement region;
        try {
            region = this.findElement(By.xpath(".//div[contains(@class, 'b-regions-tree-leaf_id_" + regionID + " ')]"));
        } catch (NoSuchElementException ex) {
            throw new DirectWebError("Не найден регион с ID " + regionID);
        }
        return new RegionSelect(region);
    }

    public static class RegionSelect extends TypifiedElement {
        protected RegionSelect(WebElement wrappedElement) {
            super(wrappedElement);
        }

        protected WebElement getCheckBox() {
            return getWrappedElement().findElement(
                    By.xpath(".//input[@class = 'b-regions-tree-leaf__checkbox']"));
        }

        protected WebElement getCollapseButton() {
            return getWrappedElement().findElement(
                    By.xpath(".//div[@class = 'b-regions-tree-leaf__collapse']"));
        }

        protected WebElement getExpandButton() {
            return getWrappedElement().findElement(
                    By.xpath(".//div[@class = 'b-regions-tree-leaf__expand']"));
        }

        protected WebElement getLabel() {
            return getWrappedElement().findElement(
                    By.xpath(".//label[@class = 'b-regions-tree-leaf__label']"));
        }

        public void expand() {
            if (!isExpanded()) {
                getExpandButton().click();
            }
        }

        public void collapse() {
            if (isExpanded()) {
                getCollapseButton().click();
            }
        }

        public void select() {
            if (!isSelected()) {
                getCheckBox().click();
            }
        }

        public void deselect() {
            if (isSelected()) {
                getCheckBox().click();
            }
        }

        public String getRegionID() {
            return getLabel().getAttribute("for").replace("p", "");
        }

        public String getRegionName() {
            return getLabel().getText();
        }

        public String getParentRegion() {
            Matcher m = Pattern.compile("parent: '\\d*'").matcher(getWrappedElement().getAttribute("onclick"));
            if (m.find()) {
                return m.group().replace("parent: '", "").replace("'", "");
            }
            throw new DirectWebError("Не удалось найти parent элемент используя onclick атрибут");
        }

        public boolean isExpanded() {
            String classString = getWrappedElement().getAttribute("class");
            if (classString.contains("b-regions-tree-leaf_expanded_no")) {
                return false;
            } else if (classString.contains("b-regions-tree-leaf_expanded_yes")) {
                return true;
            } else {
                throw new DirectWebError("Не удалось найти атрибут leaf_expanded в классе элемента");
            }
        }

        public boolean isSelected() {
            String classString = getWrappedElement().getAttribute("class");
            if (classString.contains("b-regions-tree-leaf_checked_no")) {
                return false;
            } else if (classString.contains("b-regions-tree-leaf_checked_yes")) {
                return true;
            } else {
                throw new DirectWebError("Не удалось найти атрибут leaf_checked в классе элемента");
            }
        }
    }
}
