package io.hawt.tests.features.pageobjects.pages;

import io.hawt.tests.features.pageobjects.fragments.Panel;
import io.hawt.tests.features.pageobjects.fragments.menu.Menu;
import static com.codeborne.selenide.Condition.clickable;
import static com.codeborne.selenide.Condition.cssClass;
import static com.codeborne.selenide.Condition.enabled;
import static com.codeborne.selenide.Condition.exactText;
import static com.codeborne.selenide.Condition.interactable;
import static com.codeborne.selenide.Condition.matchText;
import static com.codeborne.selenide.Condition.visible;
import static com.codeborne.selenide.Selectors.byClassName;
import static com.codeborne.selenide.Selectors.byTagName;
import static com.codeborne.selenide.Selectors.byXpath;
import static com.codeborne.selenide.Selectors.byTagAndText;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.$$;

import org.openqa.selenium.By;

import com.codeborne.selenide.SelenideElement;

/**
 * Represents Hawtio page with common methods.
 */
public class HawtioPage {
    private static final By HAWTIO_HEADER_SELECTOR = By.id("hawtio-header");
    private static final By HAWTIO_HEADER_BRAND_SELECTOR = By.id("hawtio-header-brand");

    private final Menu menu;
    private final Panel panel;

    public HawtioPage() {
        menu = new Menu();
        panel = new Panel();
    }

    public Menu menu() {
        return menu;
    }

    public Panel panel() {
        return panel;
    }

    /**
     * Click on button with a given text.
     *
     * @param text on the given button
     */
    public HawtioPage clickButton(String text) {
        $$(".pf-v6-c-button__text").findBy(exactText(text)).closest("button").shouldBe(visible).shouldBe(enabled).click();
        return this;
    }

    /**
     * Return if a button with a given text exists.
     *
     * @param text on the given button
     * @return boolean whether the button exists
     */
    public boolean buttonExists(String text) {
        return $$(".pf-v6-c-button__text").findBy(exactText(text)).closest("button").exists();
    }

    /**
     * Click on a toggle button with a given text.
     *
     * @param text on the given toggle button
     * @return this
     */
    public HawtioPage clickToggleButton(String text) {
        $$(".pf-v6-c-menu-toggle__text").findBy(matchText(text.trim())).closest("button").shouldBe(visible).shouldBe(enabled).click();
        return this;
    }

    /**
     * Click on button with a given aria-label.
     *
     * @param ariaLabel on the given button
     */
    public HawtioPage clickButtonByAriaLabel(String ariaLabel) {
        $("button[aria-label='" + ariaLabel + "']").shouldBe(clickable).click();
        return this;
    }

    /**
     * Check an alert message of a successful action.
     *
     * @return this
     */
    public HawtioPage successfulAlertMessage() {
        $(byXpath("//div[contains(@class, 'pf-v6-c-alert pf-m-success')]")).shouldBe(interactable);
        return this;
    }

    /**
     * Check an alert message of an unsuccessful action.
     *
     * @return this
     */
    public HawtioPage unsuccessfulAlertMessage() {
        $(byXpath("//div[contains(@class, 'pf-v6-c-alert pf-m-danger')]")).shouldBe(interactable);
        return this;
    }

    /**
     * Close an alert message.
     */
    public void closeAlertMessage() {
        $(byXpath("//div[contains(@class, 'pf-v6-c-alert')]//button[contains(@aria-label, 'Close')]")).shouldBe(enabled).click();
    }

    /**
     * Open a given tab.
     *
     * @param tab to be opened.
     */
    public void openTab(String tab) {
        final SelenideElement tabElement = $(byXpath("//a[text()='" + tab + "']"));
        if (!tabElement.has(cssClass("active"))) {
            tabElement.scrollTo();
            tabElement.shouldBe(enabled).click();
            tabElement.shouldHave(cssClass("active"));
        }
    }

    public SelenideElement getLogo() {
        return $(HAWTIO_HEADER_BRAND_SELECTOR).$(byClassName("pf-v6-c-brand"));
    }

    public String getAppName() {
        return $(HAWTIO_HEADER_SELECTOR).$(byTagName("h1")).text();
    }

    /**
     * Click on a button using a specific tag and text.
     */
    public HawtioPage clickButtonByTagAndText(String tag, String text) {
        $(byTagAndText(tag, text)).shouldBe(visible, enabled).click();
        return this;
    }

    /**
     * Click on an element using its data-testid attribute.
     */
    public HawtioPage clickButtonByDataTestId(String testId) {
        $("[data-testid='" + testId + "']").shouldBe(visible, enabled).click();
        return this;
    }    
}
