"""Модуль тестов контейнера для отображения событий вкладки Действия.

Содержит тесты для проверки функциональности
контейнера для отображения событий вкладки Действия.
"""

import pytest
from playwright.sync_api import Page
from pages.main_page import MainPage
from pages.login_page import LoginPage


# @pytest.mark.smoke
class TestActionsEventsContainer:
    """Класс тестов для проверки контейнера для отображения событий вкладки Действия.

    Атрибуты:
        browser: Фикстура для работы с браузером.
    """
    # @pytest.mark.develop
    def test_actions_events_tab_content(self, browser: Page) -> None:
        """Проверяет содержимое контейнера для отображения событий вкладки Действия.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        actions_events_container = mp.click_events_panel_actions_tab()
        actions_events_container.check_content()

    def test_events_tables_row_highlighting(self, browser: Page):
        """Проверяет выделение строк в таблицах событий: Реальное время и Архив.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        actions_events_container = mp.click_events_panel_actions_tab()

        actions_events_container.click_real_time_button()
        # Получение количества строк в таблице Реальное время
        rows_count = actions_events_container.get_events_table_rows_count()

        # Проверка выделения строк
        actions_events_container.check_events_table_row_highlighting(0)
        if rows_count > 1:
            actions_events_container.check_events_table_row_highlighting(rows_count - 1)
        if rows_count > 3:
            actions_events_container.check_events_table_row_highlighting(int(rows_count / 2))

        actions_events_container.click_archive_button()
        # Получение количества строк в таблице Архив
        rows_count = actions_events_container.get_events_table_rows_count()

        # Проверка выделения строк
        actions_events_container.check_events_table_row_highlighting(0)
        if rows_count > 1:
            actions_events_container.check_events_table_row_highlighting(rows_count - 1)
        if rows_count > 3:
            actions_events_container.check_events_table_row_highlighting(int(rows_count / 2))

    @pytest.mark.develop
    def test_events_table_scrolling(self, browser: Page):
        """Проверяет возможность скроллинга таблицы событий на примере таблицы Архив.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        actions_events_container = mp.click_events_panel_actions_tab()
        actions_events_container.click_archive_button()

        events_panel_position = mp.get_events_panel_position()

        # Проверка, что панель с таблицей открыта
        assert events_panel_position != "bottom", "Panel with actions events should be opened"

        is_scrollable = actions_events_container.check_events_table_verticall_scrolling()

        # Убеждаемся, что панель открыта наполовину и проверяем скроллинг
        assert events_panel_position == "center",\
               "Panel with actions events should be located on the main page center"
        assert is_scrollable, "Actions events table should be scrollable"

        # Скроллинг вниз
        actions_events_container.scroll_events_table_down()
        browser.wait_for_timeout(1000)

        # Проверка видимости последней строки после прокрутки
        actions_events_container.check_events_table_last_row_visibility()

        # Скроллинг вверх
        actions_events_container.scroll_events_table_up()
        browser.wait_for_timeout(1000)

        # Проверка видимости первой строки после прокрутки
        actions_events_container.check_events_table_first_row_visibility()

        # Раскрываем панель полностью и проверяем скроллинг
        assert mp.check_expand_more_button(), \
                "Expand more button should be present"
        mp.click_events_panel_expand_more_button()
        mp.wait_for_timeout(500)

        events_panel_position = mp.get_events_panel_position()
        assert events_panel_position == "top",\
               "Panel with actions events should be located on the main page top"

        is_scrollable = actions_events_container.check_events_table_verticall_scrolling()
        assert is_scrollable, "Actions events table should be scrollable in the full window"

        # Скроллинг вниз
        actions_events_container.scroll_events_table_down()
        browser.wait_for_timeout(1000)

        # Проверка видимости последней строки после прокрутки
        actions_events_container.check_events_table_last_row_visibility()

        # Скроллинг вверх
        actions_events_container.scroll_events_table_up()
        browser.wait_for_timeout(1000)

        # Проверка видимости первой строки после прокрутки
        actions_events_container.check_events_table_first_row_visibility()

    # @pytest.mark.develop
    def test_real_time_task_view(self, browser: Page):
        """Проверяет содержимое окна вывода информации о задаче.

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

        index = 0
        expected_task_headers = ['СООБЩЕНИЕ','СТАТУС', 'ОПИСАНИЕ']
        expected_task_stages = []

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        actions_events_container = mp.click_events_panel_actions_tab()

        actions_events_container.click_real_time_button()
        task_view_window = actions_events_container.click_events_table_row(index)

        task_view_window.check_content()

        title, task_id = task_view_window.get_window_title().split(" ")
        assert title == "Task", "Window title should start with the word 'Task'"

        stages_table_content = task_view_window.get_stages_table_content()

        task_view_window.check_stages_table_headers(stages_table_content[0], expected_task_headers)
        stages_table_content.pop(0)

        payload = {"filter": {"page": 1},
                   "count": 40}

        response = mp.send_post_api_request("e-nms/task_manager/showTaskWithFilter", payload)
        if response.status == 200:
            response_body = mp.get_response_body(response)

            if response_body:
                for item in response_body["data"]["data"]:
                    if item["id"] == task_id:
                        for stage in item["progress"]:
                            expected_task_stages.append(stage)
                        break

        assert len(expected_task_stages) > 0, f"No expected task stages found for task with id {task_id}"

        assert len (expected_task_stages) == len(stages_table_content), "Incorrect actual task stages list"
        for i in range(len(expected_task_stages)):
            expected_message = expected_task_stages[i]["message"]
            actual_message = stages_table_content[i][0]
            assert expected_message == actual_message, \
                  f"Expected message {expected_message} is not equal actual message {actual_message} for {i} row"

            expected_status = expected_task_stages[i]["status"]
            if expected_status == "ok":
                expected_status = "Норма"
            actual_status = stages_table_content[i][1]
            assert expected_status == actual_status, \
                  f"Expected message {expected_status} is not equal actual message {actual_status} for {i} row"

        task_view_window.close()

    #  TO-DO: Вернуть тесты после прояснения как должна отображаться информация в таблицах Реальное время и Архив

    # def test_events_table_column_sorting(self, browser: Page):
    #     """Проверяет сортировку колонки 'Время' в таблице событий.

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

    #     lp = LoginPage(browser)
    #     lp.do_login()

    #     mp = MainPage(browser)
    #     mp.should_be_event_panel()

    #     actions_events_container = mp.click_events_panel_actions_tab()

    #     index = 0
    #     state = actions_events_container.get_arrow_button_state(index)
    #     assert state == "down", "Arrow button should be down"

    #     actions_events_container.click_event_table_header_arrow(index)
    #     browser.wait_for_timeout(500)

    #     state = actions_events_container.get_arrow_button_state(index)
    #     assert state == "up", "Arrow button should be up"
    #     is_descending_order = actions_events_container.check_events_table_column_descending_order(index,
    #                                                                                             convert2timestamp=True)
    #     assert not is_descending_order, "Column data should be in ascending order"

    #     actions_events_container.click_event_table_header_arrow(index)
    #     browser.wait_for_timeout(500)
    #     state = actions_events_container.get_arrow_button_state(index)
    #     assert state == "down", "Arrow button should be down"
    #     is_descending_order = actions_events_container.check_events_table_column_descending_order(index,
    #                                                                                             convert2timestamp=True)
    #     assert is_descending_order, "Column data should be in descending order"

    # @pytest.mark.develop
    def test_real_time_events_table_pagination(self, browser: Page):
        """Проверяет возможность пагинации таблицы событий.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        actions_events_container = mp.click_events_panel_actions_tab()

        actions_events_container.click_real_time_button()

        actions_events_container.should_be_pagination_buttons()

        # Проверка начального состояния
        tested_pages = 1

        payload = {"filter": {"page": 1},
                   "count": 40}

        response = mp.send_post_api_request("e-nms/task_manager/showTaskWithFilter", payload)
        if response.status == 200:
            response_body = mp.get_response_body(response)

            if response_body:
                pages = response_body["data"]["pages"]

                if pages > 5:
                    tested_pages = 5
                else:
                    tested_pages = pages

        current_number = actions_events_container.get_current_data_set_number()
        assert current_number == 1, "The first page should be number one"

        if tested_pages == 1:
            actions_events_container.should_be_all_disabled()
        else:
            actions_events_container.should_be_initial_state()

            # Переход на самую последнюю страницу, возврат на страницу назад, потом на страницу вперед
            actions_events_container.click_last_page()
            browser.wait_for_timeout(2000)

            actions_events_container.should_be_final_state()

            last_number = actions_events_container.get_current_data_set_number()

            actions_events_container.click_chevron_left()
            browser.wait_for_timeout(4000)

            if last_number == 2:
                actions_events_container.should_be_initial_state()
            else:
                actions_events_container.should_be_all_enabled()

            counter = last_number - 1
            current_number = actions_events_container.get_current_data_set_number()
            assert current_number == counter, f"Expected page number {counter} is not equal actual {current_number}"

            actions_events_container.click_chevron_right()
            browser.wait_for_timeout(4000)

            actions_events_container.should_be_final_state()

            current_number = actions_events_container.get_current_data_set_number()
            assert current_number == last_number, \
                   f"Expected page number {last_number} is not equal actual {current_number}"

            # Переход на первую страницу, переход на следующую страницу, возврат на первую страницу
            actions_events_container.click_first_page()
            browser.wait_for_timeout(2000)

            actions_events_container.should_be_initial_state()

            current_number = actions_events_container.get_current_data_set_number()
            assert current_number == 1, f"Expected page number 1 is not equal actual {current_number}"

            actions_events_container.click_chevron_right()
            browser.wait_for_timeout(4000)

            if tested_pages == 2:
                actions_events_container.should_be_final_state()
            else:
                actions_events_container.should_be_all_enabled()

            current_number = actions_events_container.get_current_data_set_number()
            assert current_number == 2, f"Expected page number 2 is not equal actual {current_number}"

            actions_events_container.click_chevron_left()
            browser.wait_for_timeout(4000)

            actions_events_container.should_be_initial_state()

            current_number = actions_events_container.get_current_data_set_number()
            assert current_number == 1, f"Expected page number 1 is not equal actual {current_number}"

            if tested_pages > 2:
                # загрузка страниц от начала и до конца
                # to_do: проверка, что происходит обновление содержимого таблицы
                counter = 1

                while counter < tested_pages:
                    actions_events_container.click_chevron_right()
                    counter += 1
                    browser.wait_for_timeout(2000)

                    if counter == tested_pages:
                        actions_events_container.should_be_final_state()
                    else:
                        actions_events_container.should_be_all_enabled()
                    current_number = actions_events_container.get_current_data_set_number()
                    assert current_number == counter,\
                        f"Expected page number {counter} is not equal actual {current_number}"

                # загрузка страниц от конца к началу
                # to_do: проверка, что происходит обновление содержимого таблицы
                while counter > 2:
                    actions_events_container.click_chevron_left()
                    browser.wait_for_timeout(2000)

                    actions_events_container.should_be_all_enabled()

                    counter -= 1
                    current_number = actions_events_container.get_current_data_set_number()
                    assert current_number == counter,\
                        f"Expected page number {counter} is not equal actual {current_number}"

                # Проверка возврата к начальному состоянию
                actions_events_container.click_chevron_left()
                browser.wait_for_timeout(2000)

                actions_events_container.should_be_initial_state()

                current_number = actions_events_container.get_current_data_set_number()
                assert current_number == 1, "The first page should be number one"
