"""Модуль компонента панели навигации. Содержит класс для работы с элементами навигации."""

from playwright.sync_api import Page, Locator
from tools.logger import get_logger
from locators.navigation_panel_locators import NavigationPanelLocators
from components.base_component import BaseComponent

logger = get_logger("NAVIGATION_PANEL")


class NavigationPanelComponent(BaseComponent):
    """Компонент панели навигации. Предоставляет методы для взаимодействия с ней."""

    def __init__(self, page: Page):
        """Инициализирует компонент панели навигации.

        Args:
            page: Экземпляр страницы Playwright.
        """

        super().__init__(page)

    # Действия:
    def get_item_names(self, locator: str | Locator) -> list[str]:
        """Возвращает тексты всех элементов по указанному локатору.

        Args:
            locator: Локатор элементов или строка с CSS/XPath.

        Returns:
            Список текстов элементов.
        """

        loc = self.get_locator(locator)
        return loc.all_inner_texts()


    def click_item(self, locator: str | Locator, item_name: str) -> None:
        """Кликает по элементу с указанным текстом.

        Args:
            locator: Локатор элемента или строка с CSS/XPath.
            item_name: Текст элемента для клика.
        """

        loc = self.get_locator(locator)
        loc.get_by_text(item_name).click()

    def click_sub_item(self, locator: str | Locator, sublevel_number: int, item_name: str) -> None:
        """Кликает по вложенному элементу с указанным текстом.

        Args:
            locator: Локатор родительского элемента.
            sublevel_number: Уровень вложенности (1 или 2).
            item_name: Текст элемента для клика.

        Raises:
            ValueError: Если уровень вложенности не 1 или 2.
        """

        root_locator = self.get_locator(NavigationPanelLocators.NODE_ROOT)
        children_locator = self.get_locator(NavigationPanelLocators.NODE_CHILDREN)

        loc = self.get_locator(locator)

        if sublevel_number == 1:
            loc.locator(root_locator).get_by_text(item_name).click()
        elif sublevel_number == 2:
            loc.locator(children_locator).locator(root_locator).get_by_text(item_name).click()
        else:
            raise ValueError("the navigation panel has two levels of nesting only")

    def traverse_panel_tree(self, node_root_locator, level=0, debug=False):
        """
        Рекурсивно обходит дерево v-treeview и выводит информацию об элементах в режиме отладки (debug=True).

        Args:
            node_root_locator: Локатор для поиска корневых элементов дерева (Локатор элемента или строка с CSS/XPath).
        """
        def traverse_tree(page, root_locator, level=0, debug=False):
            # Находим все локаторы корневых узлов на текущем уровне
            nodes_count = root_locator.locator('>div.v-treeview-node').count()

            for index in range(nodes_count):
                node = root_locator.locator(f">div:nth-child({index + 1})").first

                # Извлекаем текст и аттрибуты из корневого узла
                node_text = node.inner_text()
                node_class_attr = node.get_attribute('class')

                is_expanded = False
                has_children = False

                # Проверяем лист это или начало поддерева
                if "v-treeview-node--leaf" in node_class_attr:
                    if debug:
                        print(f'[{level}][{index}] {node_text} (LEAF, Expanded: {is_expanded}, Has Children: {has_children})')
                        print("-----------------------------------------")
                else:
                    # Проверяем, является ли узел раскрытым
                    class_attr = node.locator(NavigationPanelLocators.TOGGLE_BUTTON).get_attribute('class')

                    if "v-treeview-node__toggle--open" in class_attr:
                        is_expanded = True

                    # Если узел закрыт можем его раскрыть
                    if is_expanded is False:
                        toggle_button = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
                        toggle_button.click()
                        # Ждем, пока дочерние элементы прогрузятся/появятся
                        page.wait_for_timeout(300)
                        is_expanded = True

                    # Проверяем, имеет ли узел  дочерние элементы
                    children_count = node.locator('>div.v-treeview-node__children').count()
                    content = node.locator('>div.v-treeview-node__children').inner_html()
                    if children_count > 0 and len(content) != 0:
                        has_children = True

                    edited_node_text = node_text.replace("expand_more\n", "")

                    if debug:
                        # Выводим информацию об узле
                        print(f'[{level}][{index}] {edited_node_text} (NODE, Expanded: {is_expanded}, Has Children: {has_children})')
                        print("-----------------------------------------")

                    # Рекурсивный вызов для дочерних элементов
                    # Ищем дочерние элементы *внутри* текущего узла
                    if has_children and is_expanded:
                        child_nodes_locator = root_locator.locator(f">div:nth-child({index + 1})").locator('>div.v-treeview-node__children')
                        traverse_tree(page, child_nodes_locator, level+1, debug)

        root_locator = self.get_locator(node_root_locator)
        traverse_tree(self.page, root_locator, level=level, debug=debug)

    # Проверки:
    def check_item_visibility(self, locator: str | Locator, item_name: str) -> None:
        """Проверяет видимость элемента с указанным текстом.

        Args:
            locator: Локатор элемента или строка с CSS/XPath.
            item_name: Текст элемента для проверки.

        Note:
            Временная обработка для элементов с текстом 'Шаблоны'.
        """

        msg = f"Navigation panel item '{item_name}' is not visible"

        ## временно: в навигационной панели есть две панели с именем Шаблоны
        ## для их различия добавлены индексы Шаблоны_1 для Настройки/Шаблоны
        ## Шаблоны_2 для Настройки/ZTP/Шаблоны
        loc = self.get_locator(locator)
        if item_name == "Шаблоны_1":
            loc = loc.get_by_text("Шаблоны").first
        elif item_name == "Шаблоны_2":
            loc = loc.get_by_text("Шаблоны").nth(1)
        else:
            loc = loc.get_by_text(item_name)
        self.check_presence(loc, msg)
