package com.intland.codebeamer.functionaltest.page.wiki;

import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection;
import com.intland.codebeamer.functionaltest.page.BasePage;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.util.concurrent.TimeUnit;

import static com.codeborne.selenide.Condition.not;
import static com.codeborne.selenide.Condition.selected;
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 firstSixProductLicense agreement
 * you entered into with Intland.
 */
public class WikiPropertiesPage extends BasePage {

    public enum TabType {
        PERMISSIONS("#wiki-page-permissions-tab", PermissionsTab.class);

        private final String selector;
        private final Class pageObjectClass;

        TabType(String s, Class pageObjectClass) {
            selector = s;
            this.pageObjectClass = pageObjectClass;
        }

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

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

    public ElementsCollection getInfoMessages() {
        return $$(By.xpath("//div[@id='globalMessages']/div[contains(@class, 'information')]//li"));
    }

    public ElementsCollection getErrorMessages() {
        return $$(By.xpath("//div[@id='globalMessages']/div[contains(@class, 'error')]//li"));
    }

    public Object clickOnTab(TabType tabType) {
        $(tabType.selector).click();
        return page(tabType.pageObjectClass);
    }

    public void checkIfTab(TabType tabType, Condition condition) {
        $(tabType.selector).shouldBe(condition);
    }


    abstract static class Tab extends BasePage {

        public void clickOnCancel() {
            $(By.xpath("(.//div[@id='wiki-page']/div[@class='ditch-tab-pane-wrap']/div[@class='ditch-tab-pane'])" +
                    "[count(//div[@id='wiki-page']/div[@class='ditch-tab-wrap']//div[contains(@class, 'ditch-focused')]//preceding-sibling::div)+1]" +
                    "//input[@name='_cancel']")).click();
        }

        public void clickOnSave() {
            $(By.xpath("(.//div[@id='wiki-page']/div[@class='ditch-tab-pane-wrap']/div[@class='ditch-tab-pane'])" +
                    "[count(//div[@id='wiki-page']/div[@class='ditch-tab-wrap']//div[contains(@class, 'ditch-focused')]//preceding-sibling::div)+1]" +
                    "//input[@name='SAVE']")).click();
            Wait().withTimeout(10, TimeUnit.SECONDS)
                    .ignoring(NoSuchElementException.class)
                    .until(ExpectedConditions.visibilityOf($("#overlayMessageBoxContainer")));
        }
    }

    public static class PermissionsTab extends Tab {

        public enum Permission {
            READ("Read"),
            EDIT("Edit");

            private final String selector;

            Permission(String s) {
                selector = s;
            }

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

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

        public enum Role {
            ALL("Grant/revoke to/from all*"),
            OWNER("Owner"),
            DEVELOPER("Developer"),
            PROJECT_ADMIN("Project Admin"),
            STAKEHOLDER("Stakeholder"),
            TEST_ENGINEER("Test Engineer"),
            TESTER("Tester");

            private final String selector;

            Role(String s) {
                selector = s;
            }

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

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

        public PermissionsTab() {

        }

        public void tickPermission(Role role, Permission permission, boolean selected) {
            $(By.xpath("(.//table[contains(@class, 'permissionMatrix')]/tbody//tr[./td[text()='" + permission.selector +
                    "']]//input)[count(//table[contains(@class, 'permissionMatrix')]//th[text()='" + role.selector + "']//preceding-sibling::th)]")).setSelected(selected);
        }

        public void checkIfPermission(Role role, Permission permission, Condition expectedState) {
            $(By.xpath("(.//table[contains(@class, 'permissionMatrix')]/tbody//tr[./td[text()='" + permission.selector +
                    "']]//input)[count(//table[contains(@class, 'permissionMatrix')]//th[text()='" + role.selector + "']//preceding-sibling::th)]")).shouldBe(expectedState);
        }

    }

}
