"""Модуль тестов вкладки 'Сеансы/Текущие'.

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

import pytest
from playwright.sync_api import Page, expect
from pages.login_page import LoginPage
from pages.main_page import MainPage
from pages.current_session_tab import CurrentSessionsTab
from pages.users_tab import UsersTab


# @pytest.mark.smoke
class TestCurrentSessionsTab:
    """Набор тестов для вкладки 'Сеансы/Текущие'.

    Проверяет корректность отображения и функциональность элементов вкладки сеансов,
    включая работу с сеансами пользователей, их создание, удаление и автоматическую очистку.

    Тесты покрывают следующие сценарии:
    1. test_sessions_tab_content: Тест содержимого вкладки 'Сеансы/Текущие'
    2. test_delete_session_confirm_window: Тест окна подтверждения удаления сеанса
    3. test_delete_session_after_logout: Тест автоматического удаления сеанса после выхода пользователя из системы
    4. test_delete_existed_session: Тест удаления созданного сеанса
    5. test_multiple_users_sessions: Тест создания нескольких пользователей и их сеансов
    6. test_session_removed_when_user_deleted: Тест удаления сеанса при удалении пользователя
    7. test_session_auto_deletion_after_15_minutes: Тест автоматического удаления сеанса через 15 минут после выхода пользователя
    8. test_user_cannot_delete_own_session: Тест проверки невозможности пользователя удалить свой собственный сеанс
    """


    @pytest.fixture(scope="function", autouse=True)
    def setup(self, browser: Page) -> None:
        """Фикстура для подготовки тестового окружения.

        Выполняет:
        1. Авторизацию в системе
        2. Переход на вкладку 'Сеансы/Текущие' через панель навигации
        """
        # Авторизация в системе
        login_page = LoginPage(browser)
        login_page.do_login()

        # Инициализация главной страницы
        main_page = MainPage(browser)

        # Проверка и взаимодействие с элементами навигации
        main_page.should_be_navigation_panel()
        main_page.click_main_navigation_panel_item("Настройки")
        main_page.click_subpanel_item("Обслуживание и диагностика")
        main_page.click_subpanel_item("Сеансы")
        main_page.click_subpanel_item("Текущие", parent="Сеансы")

    @pytest.fixture(scope="function")
    def cleanup_users(self, browser: Page) -> None:
        """Фикстура для очистки тестовых пользователей и их сеансов после теста."""
        yield

        # Выход из системы текущего пользователя
        mp = MainPage(browser)
        mp.do_logout()

        # Авторизация администратором для очистки
        login_page = LoginPage(browser)
        login_page.do_login()

        # Удаляем тестовых пользователей
        self._cleanup_test_users(browser)

    def _cleanup_test_users(self, browser: Page) -> None:
        """Удаляет тестовых пользователей."""
        mp = MainPage(browser)
        mp.click_main_navigation_panel_item("Настройки")
        mp.click_subpanel_item("Пользователи")
        ut = UsersTab(browser)

        # Удаляем тестовых пользователей
        test_users = ["TestUser1", "TestUser2", "TestUser3", "TestUserForSessionDeletion",
                     "TestUserForManualDeletion", "UserForAutoSessionDeletion",
                     "TestUserFor15MinDeletion", "TestUserForSelfDeletion"]

        for user_name in test_users:
            # Проверяем существует ли пользователь и удаляем его
            user_index = ut.find_user_in_table(user_name, "Администратор")
            if user_index != -1:
                ut.open_edit_user_page_by_user(user_name, "Администратор")
                ut.delete_user(user_name)

    # @pytest.mark.develop
    def test_sessions_tab_content(self, browser: Page) -> None:
        """Тест содержимого вкладки 'Сеансы'.

        Проверяет:
        1. Наличие и корректность тулбара
        2. Наличие таблицы сеансов
        3. Соответствие содержимого таблицы данным из БД
        """
        # Инициализация страницы сеансов
        sessions_tab = CurrentSessionsTab(browser)

        # Проверка элементов интерфейса
        sessions_tab.should_be_toolbar()
        sessions_tab.should_be_sessions_table()

        # Проверяем API ответ
        response = sessions_tab.send_get_api_request("e-nms/auth/sessions")
        response_body = sessions_tab.get_response_body(response)

        if not response_body:
            print("No sessions data from API - table might be empty")
            # Проверяем только заголовки
            sessions_tab.check_sessions_table_content(verify=False)
        else:
            # Проверка содержимого таблица с верификацией данных из БД
            sessions_tab.check_sessions_table_content(verify=True)


    def test_delete_session_confirm_window(self, browser: Page) -> None:
        """Тест окна подтверждения удаления сеанса.

        Проверяет:
        1. Наличие таблицы сеансов
        2. Содержимое окна подтверждения удаления сеанса
        3. Возможность горизонтального скроллинга в окне подтверждения
        4. Корректность отображения элементов интерфейса в окне подтверждения
        5. Функциональность кнопок в окне подтверждения удаления
        """
        # Инициализация страницы сеансов
        sessions_tab = CurrentSessionsTab(browser)

        # Проверка наличия таблицы сеансов
        sessions_tab.should_be_sessions_table()

        # Проверка контента и скроллинга окна подтверждения удаления сеанса
        sessions_tab.check_delete_session_confirm_window()

    def test_delete_session_after_logout(self, browser: Page, cleanup_users: None) -> None:
        """Тест автоматического удаления сеанса после выхода пользователя из системы.

        Проверяет:
        1. Создание нового пользователя
        2. Вход нового пользователя в систему
        3. Проверка наличия сеанса нового пользователя
        4. Выход нового пользователя из системы (logout)
        5. Вход в систему пользователя admin
        6. Проверка отсутствия сеанса нового пользователя
        7. Удаление пользователя выполняется автоматически фикстурой cleanup_users
        """
        user_data = {"name": "TestUserForSessionDeletion", "role": "Администратор", "password": "qwerty1234567"}

        mp = MainPage(browser)
        ut = UsersTab(browser)

        # Создание нового пользователя
        mp.click_subpanel_item("Пользователи")
        ut.open_add_user_window()
        ut.add_new_user(user_data)

        # Обновление списка пользователей (двойной клик - возможно баг?)
        mp.click_subpanel_item("Пользователи")
        mp.click_subpanel_item("Пользователи")

        # Проверка наличия пользователя в таблице
        ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход в систему для нового пользователя
        new_lp = LoginPage(browser)
        new_lp.do_login(username=user_data["name"], password=user_data["password"])

        # Инициализация главной страницы
        new_mp = MainPage(browser)

        # Открыть вкладку Сеансы
        new_mp.should_be_navigation_panel()
        new_mp.click_main_navigation_panel_item("Настройки")
        new_mp.click_subpanel_item("Обслуживание и диагностика")
        new_mp.click_subpanel_item("Сеансы")
        new_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Инициализация страницы сеансов
        st = CurrentSessionsTab(browser)

        # # Проверка наличия таблицы сеансов
        st.should_be_sessions_table()

        # Проверка наличия записи о сеансе текущего пользователя
        session_token = st.get_session_token()
        st.should_be_session_in_table(session_token)

        # logout
        new_mp.do_logout()

        # Авторизация в системе предыдущего пользователя
        admin_lp = LoginPage(browser)
        admin_lp.do_login()

        # Инициализация главной страницы
        admin_mp = MainPage(browser)

        # Открыть вкладку Сеансы
        admin_mp.should_be_navigation_panel()
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Обслуживание и диагностика")
        admin_mp.click_subpanel_item("Сеансы")
        admin_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Проверка наличия таблица сеансов
        st.should_be_sessions_table()

        # Проверка отсутствия записи о сеансе созданного пользователя после выхода из системы
        st.should_not_be_session_in_table(session_token)

        # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста

    def test_delete_existed_session(self, browser: Page, cleanup_users: None) -> None:
        """Тест удаления созданного сеанса.

        Проверяет:
        1. Создание нового пользователя
        2. Вход нового пользователя в систему
        3. Проверка наличия сеанса нового пользователя
        4. Выход нового пользователя из системы (logout)
        5. Вход в систему пользователя admin
        6. Удаление сеанса нового пользователя
        7. Проверка отсутствия сеанса нового пользователя
        8. Удаление пользователя выполняется автоматически фикстурой cleanup_users
        """
        user_data = {"name": "TestUserForManualDeletion", "role": "Администратор", "password": "qwerty1234567"}

        mp = MainPage(browser)
        ut = UsersTab(browser)

        # Создание нового пользователя NewUser
        mp.click_subpanel_item("Пользователи")
        ut.open_add_user_window()
        ut.add_new_user(user_data)

        # Обновление списка пользователей (двойной клик - возможно баг?)
        mp.click_subpanel_item("Пользователи")
        mp.click_subpanel_item("Пользователи")

        # Проверка наличия пользователя в таблице
        ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход в систему для нового пользователя NewUser
        new_lp = LoginPage(browser)
        new_lp.do_login(username=user_data["name"], password=user_data["password"])

        # Инициализация главной страницы
        new_mp = MainPage(browser)

        # Открыть вкладку Сеанса
        new_mp.should_be_navigation_panel()
        new_mp.click_main_navigation_panel_item("Настройки")
        new_mp.click_subpanel_item("Обслуживание и диагностика")
        new_mp.click_subpanel_item("Сеансы")
        new_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Инициализация страницы сеансов
        st = CurrentSessionsTab(browser)

        # Проверка наличия таблицы сеансов
        st.should_be_sessions_table()

        # Проверка наличия записи о сеансе текущего пользователя
        new_user_token = st.get_session_token()
        st.should_be_session_in_table(new_user_token)

        # Авторизация в системе пользователя admin
        admin_lp = LoginPage(browser)
        admin_lp.do_login()

        # Переход на вкладку Сеансы
        admin_mp = MainPage(browser)
        admin_mp.should_be_navigation_panel()
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Обслуживание и диагностика")
        admin_mp.click_subpanel_item("Сеансы")
        admin_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Удаление сеанса созданного пользователя по токену
        admin_sessions_tab = CurrentSessionsTab(browser)
        admin_sessions_tab.should_be_sessions_table()
        admin_sessions_tab.delete_session_by_token(new_user_token)

        # Проверка отсутствия записи о сеансе созданного пользователя после удаления
        admin_sessions_tab.should_not_be_session_in_table(new_user_token)

        # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста

    def test_multiple_users_sessions(self, browser: Page, cleanup_users: None) -> None:
        """Тест создания нескольких пользователей и их сеансов.

        Проверяет:
        1. Создание нескольких пользователей User1..User3
        2. Вход каждого пользователя в систему и создание сеансов
        3. Проверка наличия сеанса в таблице
        4. Проверка скроллинга таблицы с множеством сеансов
        5. Проверка подсветки строк таблицы
        6. Удаление пользователей выполняется автоматически фикстурой cleanup_users
        """
        users_data = [
            {"name": "TestUser1", "role": "Администратор", "password": "password123456"},
            {"name": "TestUser2", "role": "Администратор", "password": "password234567"},
            {"name": "TestUser3", "role": "Администратор", "password": "password345678"}
        ]

        session_tokens = []

        mp = MainPage(browser)
        ut = UsersTab(browser)
        mp.click_subpanel_item("Пользователи")

        # Создание нескольких пользователей
        for user_data in users_data:
            mp.click_subpanel_item("Пользователи")
            mp.click_subpanel_item("Пользователи")
            ut.open_add_user_window()
            ut.add_new_user(user_data)

            # Проверка наличия пользователя в таблице
            ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход каждого пользователя и получение токенов сеансов
        for user_data in users_data:
            # Вход новым пользователем
            login_page = LoginPage(browser)
            login_page.do_login(username=user_data["name"], password=user_data["password"])

            # Получение токена сеансов
            sessions_tab = CurrentSessionsTab(browser)
            #sessions_tab.should_be_sessions_table()
            session_token = sessions_tab.get_session_token()
            session_tokens.append(session_token)

        # Возврат администратора для проверки сеансов
        login_page = LoginPage(browser)
        login_page.do_login()

        mp = MainPage(browser)
        mp.click_main_navigation_panel_item("Настройки")
        mp.click_subpanel_item("Обслуживание и диагностика")
        mp.click_subpanel_item("Сеансы")
        mp.click_subpanel_item("Текущие", parent="Сеансы")

        sessions_tab = CurrentSessionsTab(browser)
        sessions_tab.should_be_sessions_table()

        # Проверка наличия сеансов всех пользователей
        for session_token in session_tokens:
            sessions_tab.should_be_session_in_table(session_token)

        # Проверка скроллинга таблицы с множеством сеансов
        self._test_sessions_table_scrolling(sessions_tab)

        # Проверка подсветки строк таблицы
        rows_count = sessions_tab.get_rows_count()
        browser.wait_for_timeout(1000)

        # Проверка подсветки первой строки
        sessions_tab.check_sessions_table_row_highlighting(0)

        # Проверка подсветки последней строки (если в таблице более одной строки)
        if rows_count > 1:
            browser.wait_for_timeout(1000)
            sessions_tab.check_sessions_table_row_highlighting(rows_count - 1)

    def _test_sessions_table_scrolling(self, sessions_tab: CurrentSessionsTab) -> None:
        """Вспомогательный метод для проверки скроллинга таблицы сеансов.

        Проверяет:
        1. Возможность вертикального скроллинга таблицы
        2. Видимость первой и последней строк после скроллинга
        """
        # Проверка возможности вертикального скроллинга
        is_scrollable = sessions_tab.check_sessions_table_verticall_scrolling()

        if is_scrollable:
            print("Таблица поддерживает вертикальный скроллинг")

            # Прокрутка вниз
            sessions_tab.scroll_sessions_table_down()

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

            # Прокрутка вверх
            sessions_tab.scroll_sessions_table_up()

            # Проверка видимости первой строки после прокрутки
            sessions_tab.check_sessions_table_first_row_visibility()
        else:
            print("Таблица не поддерживает вертикальный скроллинг - проверяем базовую функциональность")

            # Проверка видимости первой строки
            sessions_tab.check_sessions_table_first_row_visibility()

    @pytest.mark.skip(reason="Не реализовано разработчиком")
    def test_session_removed_when_user_deleted(self, browser: Page, cleanup_users: None) -> None:
        """Тест удаления сеанса при удалении пользователя.

        Проверяет:
        1. Создание нового пользователя
        2. Вход пользователя и создание сеанса
        3. Удаление пользователя администратором
        4. Проверка автоматического удаления сеанса пользователя
        """
        user_data = {"name": "UserForAutoSessionDeletion", "role": "Администратор", "password": "qwerty123"}

        mp = MainPage(browser)
        ut = UsersTab(browser)

        # Создание нового пользователя
        mp.click_subpanel_item("Пользователи")
        ut.open_add_user_window()
        ut.add_new_user(user_data)

        # Обновление списка пользователей
        mp.click_subpanel_item("Пользователи")
        mp.click_subpanel_item("Пользователи")

        # Проверка наличия пользователя в таблице
        ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход в систему для нового пользователя
        new_lp = LoginPage(browser)
        new_lp.do_login(username=user_data["name"], password=user_data["password"])

        # Получение токена сеанса нового пользователя
        new_mp = MainPage(browser)

        # Открыть вкладку Сеансы
        new_mp.should_be_navigation_panel()
        new_mp.click_main_navigation_panel_item("Настройки")
        new_mp.click_subpanel_item("Обслуживание и диагностика")
        new_mp.click_subpanel_item("Сеансы")
        new_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Получаем токен сеанса
        sessions_tab = CurrentSessionsTab(browser)
        new_user_token = sessions_tab.get_session_token()

        # Проверка наличия сеанса в таблице
        sessions_tab.should_be_session_in_table(new_user_token)

        # Выход из системы нового пользователя
        new_mp.do_logout()

        # Авторизация администратором
        admin_lp = LoginPage(browser)
        admin_lp.do_login()

        # Переход на вкладку Пользователи
        admin_mp = MainPage(browser)
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Пользователи")

        # Удаление пользователя
        admin_ut = UsersTab(browser)
        admin_ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
        admin_ut.delete_user(user_data["name"])

        # Переход на вкладку Сеансы
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Обслуживание и диагностика")
        admin_mp.click_subpanel_item("Сеансы")
        admin_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Проверка отсутствия сеанса после удаления пользователя
        admin_sessions_tab = CurrentSessionsTab(browser)
        admin_sessions_tab.should_be_sessions_table()

        # Сеанс должна автоматически удалиться при удалении пользователя
        admin_sessions_tab.should_not_be_session_in_table(new_user_token)

    @pytest.mark.skip(reason="Временно исключено из тестирования. Долгий тест 15 минут.")
    def test_session_auto_deletion_after_15_minutes(self, browser: Page, cleanup_users: None) -> None:
        """Тест автоматического удаления сеанса через 15 минут после выхода пользователя.

        Проверяет:
        1. Создание нового пользователя
        2. Вход пользователя и создание сеанса
        3. Выход пользователя из системы
        4. Ожидание 15 минут
        5. Проверка автоматического удаления сеанса по истечении времени
        6. Удаление пользователя выполняется автоматически фикстурой cleanup_users
        """
        user_data = {"name": "TestUserFor15MinDeletion", "role": "Администратор", "password": "qwerty123"}

        mp = MainPage(browser)
        ut = UsersTab(browser)

        # Создание нового пользователя
        mp.click_subpanel_item("Пользователи")
        ut.open_add_user_window()
        ut.add_new_user(user_data)

        # Обновление списка пользователей
        mp.click_subpanel_item("Пользователи")
        mp.click_subpanel_item("Пользователи")

        # Проверка наличия пользователя в таблице
        ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход в систему для нового пользователя
        new_lp = LoginPage(browser)
        new_lp.do_login(username=user_data["name"], password=user_data["password"])

        # Получение токена сеанса нового пользователя
        new_mp = MainPage(browser)

        # Открыть вкладку Сеансы
        new_mp.should_be_navigation_panel()
        new_mp.click_main_navigation_panel_item("Настройки")
        new_mp.click_subpanel_item("Обслуживание и диагностика")
        new_mp.click_subpanel_item("Сеансы")
        new_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Получаем токен сеанса
        sessions_tab = CurrentSessionsTab(browser)
        session_token = sessions_tab.get_session_token()

        # Проверка наличия сеанса в таблице
        sessions_tab.should_be_session_in_table(session_token)

        # Выход из системы нового пользователя
        new_mp.do_logout()

        # Авторизация администратором
        admin_lp = LoginPage(browser)
        admin_lp.do_login()

        # Переход на вкладку Сеансы
        admin_mp = MainPage(browser)
        admin_mp.should_be_navigation_panel()
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Обслуживание и диагностика")
        admin_mp.click_subpanel_item("Сеансы")
        admin_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Проверка наличия сеанса сразу после выхода
        admin_sessions_tab = CurrentSessionsTab(browser)
        admin_sessions_tab.should_be_session_in_table(session_token)

        admin_mp.do_logout()

        # Ожидание 15 минут 1 секунда (901 секунд)
        print("Ожидание 15 минут для автоматического удаления сеанса...")
        browser.wait_for_timeout(901000)  # 15 минут 1 секунда в миллисекундах

        # Авторизация администратором
        admin_lp = LoginPage(browser)
        admin_lp.do_login()

        # Повторный переход на вкладку Сеансы после обновления
        admin_mp = MainPage(browser)
        admin_mp.should_be_navigation_panel()
        admin_mp.click_main_navigation_panel_item("Настройки")
        admin_mp.click_subpanel_item("Обслуживание и диагностика")
        admin_mp.click_subpanel_item("Сеансы")
        admin_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Проверка отсутствия сеанса после 15 минут
        admin_sessions_tab = CurrentSessionsTab(browser)
        admin_sessions_tab.should_be_sessions_table()
        admin_sessions_tab.should_not_be_session_in_table(session_token)

        # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста

    @pytest.mark.skip(reason="Не реализован разработчиком, требует проверки бизнес-логики")
    def test_user_cannot_delete_own_session(self, browser: Page, cleanup_users: None) -> None:
        """Тест проверки невозможности пользователя удалить свой собственный сеанс.
        Проверяет:
        1. Создание нового пользователя
        2. Вход пользователя и создание сеанса
        3. Попытку удаления своего собственного сеанса
        4. Проверку, что кнопка удаления недоступна или скрыта
        5. Удаление пользователя выполняется автоматически фикстурой cleanup_users
        """
        user_data = {"name": "TestUserForSelfDeletion", "role": "Администратор", "password": "qwerty123"}

        mp = MainPage(browser)
        ut = UsersTab(browser)

        # Создание нового пользователя
        mp.click_subpanel_item("Пользователи")
        ut.open_add_user_window()
        ut.add_new_user(user_data)

        # Обновление списка пользователей
        mp.click_subpanel_item("Пользователи")
        mp.click_subpanel_item("Пользователи")

        # Проверка наличия пользователя в таблице
        ut.should_be_user_in_table(user_data["name"], user_data["role"])

        # Вход в систему для нового пользователя
        new_lp = LoginPage(browser)
        new_lp.do_login(username=user_data["name"], password=user_data["password"])

        # Переход на вкладку Сеансы
        new_mp = MainPage(browser)
        new_mp.should_be_navigation_panel()
        new_mp.click_main_navigation_panel_item("Настройки")
        new_mp.click_subpanel_item("Обслуживание и диагностика")
        new_mp.click_subpanel_item("Сеансы")
        new_mp.click_subpanel_item("Текущие", parent="Сеансы")

        # Получаем токен сеанса
        sessions_tab = CurrentSessionsTab(browser)
        session_token = sessions_tab.get_session_token()

        # Проверка наличия сеанса в таблице
        sessions_tab.should_be_session_in_table(session_token)

        # Попытка найти кнопку удаления для своего сеанса
        row_index = sessions_tab.find_session_in_table(session_token)

        # Проверяем, что кнопка удаления либо отсутствует, либо неактивна
        delete_button = sessions_tab.get_delete_session_button_from_row(row_index)

        # Проверяем, что кнопка либо не видима, либо отключена
        expect(delete_button).not_to_be_visible()

        # Выход из системы
        new_mp.do_logout()

        # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста
