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

from playwright.sync_api import Page, expect, Locator
from tools.logger import get_logger
from components.base_component import BaseComponent


logger = get_logger("TABLE")


class TableComponent(BaseComponent):
    """Компонент таблицы. Предоставляет методы для работы с табличными данными."""

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

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

        super().__init__(page)

    # Действия:
    def get_row_locator(self, table_locator: str | Locator, row_index: int) -> Locator | None:
        """Возвращает локатор строки по индексу.

        Args:
            table_locator: Локатор таблицы.
            row_index: Индекс строки.

        Returns:
            Локатор строки или None, если индекс вне диапазона.
        """

        table = self.get_locator(table_locator)

        rows = table.locator("//tbody/tr")

        if row_index in range(rows.count()):
            return rows.nth(row_index)
        else:
            return None

    def read(self, locator: str | Locator) -> list[list[str]]:
        """Читает данные таблицы, включая заголовки.

        Args:
            locator: Локатор таблицы.

        Returns:
            Двумерный список с данными таблицы.
        """

        table_data = []
        table = self.get_locator(locator)

        # Чтение заголовка таблицы
        header_cells = table.locator("//thead/tr")
        header_cell_text = header_cells.nth(0).inner_text()
        header_data = header_cell_text.split('\n')
        table_data.append(header_data)

        # Чтение ячеек таблицы
        rows = table.locator("//tbody/tr")
        for i in range(rows.count()):
            row = rows.nth(i)
            cells = row.locator("td")
            row_data = []
            for j in range(cells.count()):
                cell_text = cells.nth(j).inner_text()
                row_data.append(cell_text)
            table_data.append(row_data)

        return table_data

    # Проверки:
    def check_first_row_visibility(self, locator: str | Locator) -> None:
        """Проверяет видимость первой строки таблицы.

        Args:
            locator: Локатор таблицы.
        """

        table = self.get_locator(locator)
        first_row = table.locator("//tbody/tr").first
        expect(first_row).to_be_visible(), "The first table row is not visible"

    def check_last_row_visibility(self, locator: str | Locator) -> None:
        """Проверяет видимость последней строки таблицы.

        Args:
            locator: Локатор таблицы.
        """

        table = self.get_locator(locator)
        last_row = table.locator("//tbody/tr").last
        expect(last_row).to_be_visible(), "The last table row is not visible"

    def check_row_highlighting(self, locator: str | Locator, row_index: int) -> None:
        """Проверяет изменение цвета строки при наведении.

        Args:
            locator: Локатор таблицы.
            row_index: Индекс проверяемой строки.
        """

        table = self.get_locator(locator)
        row = table.locator("//tbody/tr").nth(row_index)

        row.scroll_into_view_if_needed()
        hover_element = row.locator(".body-row-hover")
        initial_color = hover_element.evaluate("el => window.getComputedStyle(el).backgroundColor")

        row.hover()
        self.page.wait_for_timeout(300)

        new_color = hover_element.evaluate("el => window.getComputedStyle(el).backgroundColor")
        assert initial_color != new_color, "Color of row did not change when hovering the cursor"
