"""Модуль компонента тулбара (панели инструментов).

Содержит класс ToolbarComponent для работы с элементами тулбара:
- Управление кнопками и их подсказками
- Проверка видимости элементов
- Взаимодействие с панелью инструментов
"""

from playwright.sync_api import Page, expect, Locator
from tools.logger import get_logger
from locators.toolbar_locators import ToolbarLocators
from elements.tooltip_button_element import TooltipButton
from elements.tab_button_element import TabButton
from elements.button_element import Button
from components.base_component import BaseComponent

logger = get_logger("TOOLBAR")


class ToolbarComponent(BaseComponent):
    """Компонент тулбара. Предоставляет методы для работы с панелью инструментов.

    Args:
        page (Page): Экземпляр страницы Playwright
        title (str): Заголовок тулбара
    """

    def __init__(self, page: Page, title: str) -> None:
        """Инициализирует компонент тулбара с указанным заголовком."""
        super().__init__(page)
        self.title = title
        self.buttons = []

    # Действия:
    def add_title(self, title: str) -> None:
        """Устанавливает новый заголовок тулбара.

        Args:
            title (str): Новый заголовок
        """
        self.title = title

    def add_tooltip_button(self, locator: Locator, name: str) -> None:
        """Добавляет кнопку с подсказкой в тулбар.

        Args:
            locator (Locator): Локатор кнопки
            name (str): Уникальное имя кнопки
        """
        self.buttons.append(TooltipButton(self.page, locator, name))

    def add_tab_button(self, locator: Locator, name: str) -> None:
        """Добавляет кнопку типа v-tab в тулбар.

        Args:
            locator (Locator): Локатор кнопки
            name (str): Уникальное имя кнопки
        """
        self.buttons.append(TabButton(self.page, locator, name))

    def add_button(self, locator: Locator, name: str) -> None:
        """Добавляет кнопку в тулбар.

        Args:
            locator (Locator): Локатор кнопки
            name (str): Уникальное имя кнопки
        """
        self.buttons.append(Button(self.page, locator, name))

    def get_button_by_name(self, name: str
                          ) -> TooltipButton | TabButton | Button | None:
        """Возвращает кнопку по имени.

        Args:
            name (str): Имя кнопки

        Returns:
            TooltipButton | TabButton | Button | None: Найденная кнопка или None
        """
        for button in self.buttons:
            if button.name == name:
                return button
        return None

    def click_button(self, name: str) -> None:
        """Кликает по кнопке тулбара.

        Args:
            name (str): Имя кнопки

        Raises:
            AssertionError: Если кнопка не найдена
        """
        button = self.get_button_by_name(name)
        if button is None:
            raise AssertionError(f"Unsupported button name {name}")
        button.click()

    def get_toolbar_title_text(self, locator: str = ToolbarLocators.TITLE,
                              filter_text: str | None = None,
                              timeout: int = 5000) -> str:
        """Получает заголовок тулбара окна.

        Args:
            locator: Локатор для заголовка тулбара
            filter_text: Текст для фильтрации заголовка (опционально)
            timeout: Таймаут ожидания в миллисекундах

        Returns:
            str: Текст заголовка тулбара

        Raises:
            Exception: Если не удалось получить заголовок
        """
        # Получаем локатор заголовка
        title_locator = self.get_locator(locator)

        # Фильтруем по тексту если указан
        if filter_text:
            title_locator = title_locator.filter(has_text=filter_text)

        # Ждем появления заголовка с помощью expect
        expect(title_locator).to_be_visible(timeout=timeout)

        # Получаем текст заголовка
        title_text = title_locator.text_content().strip()
        logger.info("Toolbar title: '%s'", title_text)

        return title_text

    # Проверки:
    def is_button_present(self, name: str) -> bool:
        """Проверяет наличие кнопки.

        Args:
            name (str): Имя кнопки

        Returns:
            bool: True если кнопка присутствует

        Raises:
            AssertionError: Если имя кнопки не поддерживается
        """
        button = self.get_button_by_name(name)
        if button is None:
            raise AssertionError(f"Unsupported button name {name}")
        return button.is_present(timeout=1000)  # Ожидание 1 секунда

    def is_button_not_present(self, name: str) -> bool:
        """Проверяет отсутствие кнопки.

        Args:
            name (str): Имя кнопки

        Returns:
            bool: True если кнопка отсутствует

        Raises:
            AssertionError: Если имя кнопки не поддерживается
        """
        button = self.get_button_by_name(name)
        if button is None:
            raise AssertionError(f"Unsupported button name {name}")
        return button.is_not_present(timeout=1000)  # Ожидание 1 секунда

    def check_toolbar_presence(self, message: str) -> None:
        """Проверяет видимость тулбара.

        Args:
            message (str): Сообщение об ошибке если тулбар не виден
        """
        locator = self.get_locator(ToolbarLocators.TITLE).filter(
            has_text=self.title
        )
        expect(locator).to_be_visible(), message

    def check_toolbar_presence_by_locator(self, locator: str | Locator,
                                         message: str) -> None:
        """Проверяет видимость тулбара.

        Args:
            locator: Локатор тулбара
            message (str): Сообщение об ошибке если тулбар не виден
        """
        locator = self.get_locator(locator)
        expect(locator).to_be_visible(), message

    def check_toolbar_presence_by_locator_and_title(self, locator: str | Locator,
                                                   message: str) -> None:
        """Проверяет видимость тулбара.

        Args:
            locator: Локатор тулбара
            message (str): Сообщение об ошибке если тулбар не виден
        """
        locator = self.get_locator(locator).filter(has_text=self.title)
        expect(locator).to_be_visible(), message

    def check_button_visibility(self, name: str) -> None:
        """Проверяет наличие и видимость кнопки с предварительной прокруткой.

        Args:
            name (str): Имя кнопки

        Raises:
            AssertionError: Если кнопка не найдена или не видна
        """
        button = self.get_button_by_name(name)

        if button is None:
            raise AssertionError(f"Unsupported button name {name}")

        button.locator.scroll_into_view_if_needed()
        button.check_visibility(f"Button with name {name} is missing")

    def check_button_tooltip(self, name: str, tooltip: str) -> None:
        """Проверяет текст подсказки кнопки.

        Args:
            name (str): Имя кнопки
            tooltip (str): Ожидаемый текст подсказки

        Raises:
            AssertionError: Если текст подсказки не совпадает
        """
        button = self.get_button_by_name(name)
        if button is None:
            raise AssertionError(f"Unsupported button name {name}")
        button.check_tooltip_with_text(tooltip)
