package com.intland.codebeamer.functionaltest.page.trackers.documentview;

import com.codeborne.selenide.CollectionCondition;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement;
import com.intland.codebeamer.functionaltest.helper.Helper;
import com.intland.codebeamer.functionaltest.page.BasePage;
import com.intland.codebeamer.functionaltest.page.common.EditorComponent;
import com.intland.codebeamer.functionaltest.page.trackers.TrackerItemDetailsPage;
import com.intland.codebeamer.functionaltest.page.common.ConfirmationDialogPage;
import com.intland.codebeamer.functionaltest.page.trackers.*;
import org.openqa.selenium.By;

import static com.codeborne.selenide.Condition.disappear;
import static com.codeborne.selenide.Selenide.*;

/**
 * Copyright by Intland Software
 * <p>
 * All rights reserved.
 * <p>
 * This software is the confidential and proprietary information
 * of Intland Software. ("Confidential Information"). You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Intland.
 */
public class LeftPane {

    public SelenideElement leftPane() {
        return $("#west");
    }

    public SelenideElement leftTreePane() {
        return $("#treePane");
    }

    public SelenideElement treeFilter() {
        return $(".treeFilterBox");
    }

    private final String leftTreeItemSelector = ".//li[@role='treeitem' and not(contains(@class, 'jstree-hidden'))]/a";

    public enum LeftTreeContextMenuItem {
        OPEN("Open", TrackerItemDetailsPage.class),
        COLLAPSE_NODE("Collapse Node", null),
        EXPAND_NODE("Expand Node", null),
        RENAME("Rename", null),
        COPY("Copy", null),
        PASTE_AS_NEW_CHILD("Paste as New Child", AssociationTypeSelectionDialogPage.class),
        PASTE_ABOVE_THIS("Paste Above This", AssociationTypeSelectionDialogPage.class),
        PASTE_BELOW_THIS("Paste Below This", AssociationTypeSelectionDialogPage.class),
        DELETE("Delete...", ConfirmationDialogPage.class),
        SHOW_TREE_FROM_THIS_ITEM("Show tree from this item", null),
        GO_TO_ROOT("Go to Root Item", null),
        NEW_CHILD("New Child", null),
        INSERT_NEW_ITEM_AFTER_THIS("Insert a new Item after this", null),
        INSERT_NEW_ITEM_BEFORE_THIS("Insert a new Item before this", null),
        EXPORT_SELECTION("Export selection", ExportToOfficeDialogPage.class);

        private final String text;
        public final Class<?> pageObjectClass;

        LeftTreeContextMenuItem(String s, Class<?> pageObjectClass) {
            text = s;
            this.pageObjectClass = pageObjectClass;
        }

        public boolean equalsName(String otherSelector) {
            return (otherSelector == null) ? false : text.equals(otherSelector);
        }

        public String toString() {
            return this.text;
        }
    }

    public enum DragAndDropAction {
        BEFORE,
        INTO,
        AFTER;
    }


    /**
     * @param itemLabel
     * @param index     If the label is not unique enough there are multiple results so with this parameter you can choose one of those
     * @return
     */
    public SelenideElement leftTreeItem(String itemLabel, int index) {
        openAllLeftTreeNodes();
        return leftTreePane().find(By.xpath("(" + leftTreeItemSelector + "[contains(text(), '" + itemLabel + "')])" + "[" + index + "]"));
    }

    public ElementsCollection getAllLeftTreeItems() {
        openAllLeftTreeNodes();
        return leftTreePane().findAll(By.xpath(leftTreeItemSelector));
    }

    public ElementsCollection getAllLeftTreeItems(boolean doOpenAll) {
        if (doOpenAll) openAllLeftTreeNodes();
        return leftTreePane().findAll(By.xpath(leftTreeItemSelector));
    }

    public SelenideElement clickOnLeftTreeItem(String itemLabel, int index) {
        SelenideElement item = leftTreeItem(itemLabel, index);
        item.click();
        return item;
    }

    public BasePage clickOnLeftTreeContextMenuItem(String itemLabel, int index, LeftTreeContextMenuItem leftTreeContextMenuItem) {
        clickOnLeftTreeItem(itemLabel, index).contextClick();
        $(By.xpath("//ul[contains(@class, 'jstree-contextmenu')]//a[contains(text(), '" + leftTreeContextMenuItem.text + "')]")).click();
        return leftTreeContextMenuItem.pageObjectClass != null ? page((Class<BasePage>) leftTreeContextMenuItem.pageObjectClass) : null;
    }

    public void dragAndDrop(String itemLabelFrom, int itemLabelFromIndex, String itemLabelTo, int itemLabelToIndex, DragAndDropAction dragAndDropAction) {
        openAllLeftTreeNodes();
        SelenideElement to = leftTreeItem(itemLabelTo, itemLabelToIndex);
        int xOffset = to.getSize().getWidth()/2;
        int yOffset = 0;
        if (dragAndDropAction.equals(DragAndDropAction.BEFORE)) {
            yOffset = 0;
        } else if (dragAndDropAction.equals(DragAndDropAction.INTO)) {
            yOffset = to.getSize().getHeight() / 2;
        } else if (dragAndDropAction.equals(DragAndDropAction.AFTER)) {
            yOffset = to.getSize().getHeight() - 1;
        }
        actions().clickAndHold(leftTreeItem(itemLabelFrom, itemLabelFromIndex)).moveToElement(to, xOffset, yOffset).release().perform();
        sleep(1000);
    }

    public void fillTreeFilter(String searchQuery) {
        treeFilter().setValue(searchQuery);
        $("#go_treePane").click();
        sleep(1000);
    }

    public EditorComponent clickOnPlusIcon() {
        leftPane().find(By.xpath(".//img[@title='New Test Case']")).click();
        return new EditorComponent();
    }

    public SettingsDialog clickOnSettingsIcon() {
        leftPane().find(By.xpath(".//img[@title='Settings']")).click();
        return page(SettingsDialog.class);
    }

    public BaselinesDialog clickOnBaselinesIcon() {
        leftPane().find(By.xpath(".//img[@title='Baselines']")).click();
        return page(BaselinesDialog.class);
    }

    public void moveLeftTreeItemToReleaseItem(String releaseItemName, int releaseItemIndex, String leftTreeItemName, int leftTreeItemIndex) {
        RightPane rightPane = page(RightPane.class);
        rightPane.releasesTab.openAllReleasesTreeItem();
        SelenideElement releaseItem = rightPane.releasesTab.releasesTreePane().find(By.xpath("(.//li[@role='treeitem' and not(contains(@class, 'jstree-hidden'))]/a[text()='" + releaseItemName + "'])[" + releaseItemIndex + "]"));
        SelenideElement leftTreeItem = page(DocumentViewPage.class).leftPane.leftTreeItem(leftTreeItemName, leftTreeItemIndex);
        actions().clickAndHold(leftTreeItem).moveToElement(releaseItem).release().build().perform();
    }
//    public void cancelSubtree() {
//        List<WebElement> pinIcon = leftTreePaneSelector().findElements(By.className("pin-icon"));
//        if (pinIcon.isEmpty()) return;
//        sleep(1000);
//        pinIcon.get(0).click();
//        cancelSubtree();
//    }


    public boolean isLeftPaneHidden() {
        return leftPane().getCssValue("display").equals("none");
    }

    public int getLeftPaneWidth() {
        return Integer.parseInt(leftPane().getCssValue("width").split("px")[0]);
    }

    public boolean isLeftTreeItemEditable(String itemLabel) {
        return leftTreePane().find(By.xpath(".//li[@title='" + itemLabel + "' and @editable='true']")).exists();
    }

    public void checkIfNewRequirementIcon(Condition condition) {
        leftPane().find(By.xpath(".//img[@title='New Requirement']")).shouldBe(condition);
    }

    public void checkIfContextMenuItems(String itemLabel, int index, Condition condition, LeftTreeContextMenuItem... items) {
        clickOnLeftTreeItem(itemLabel, index).contextClick();
        if (Condition.visible.getClass().equals(condition.getClass())) {
            $$(By.xpath(".//ul[contains(@class, 'jstree-contextmenu')]//li[not(contains(@class, 'vakata-context'))]")).shouldHave(CollectionCondition.size(items.length));
        }
        for (LeftTreeContextMenuItem item : items) {
            $(By.xpath("//ul[contains(@class, 'jstree-contextmenu')]//a[contains(text(), '" + item.text + "')]")).shouldBe(condition);
        }

    }

    public void openAllLeftTreeNodes(){
        waitForLeftTreeToLoad();
        Helper.openAllRootNodes(leftTreePane());
    }

    public void waitForLeftTreeToLoad() {
        $("#j1_loading").should(disappear);
    }

}
