"""Модуль тестов вкладки 'Пользователи'.

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

from typing import Dict
from playwright.sync_api import Page
from pages.users_tab import UsersTab
from pages.main_page import MainPage
from pages.login_page import LoginPage

# @pytest.mark.smoke
class TestUsersTabAddUser:
    """Класс тестов для проверки вкладки 'Пользователи' - действия при создании пользователя.

    Тесты покрывают следующие сценарии:
    1. test_add_user_window_content: Проверяет содержимое окна добавления пользователя
    2. test_add_user_window_close_buttons: Проверяет кнопки закрытия окна добавления
    3. test_add_local_user: Проверяет добавление локального пользователя
    4. test_add_AD_user: Проверяет добавление пользователя Active Directory
    """

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

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_navigation_panel()
        mp.click_main_navigation_panel_item("Настройки")
        mp.click_subpanel_item("Пользователи")

    @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 = ["TestUser", "TestUserAD"]

        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_add_user_window_content(self, browser: Page) -> None:
        """Проверяет содержимое окна добавления пользователя.

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

        ut = UsersTab(browser)
        
        ut.open_add_user_window()
        ut.check_add_user_window_content()
        ut.transform_to_add_AD_user_window()
        ut.check_add_AD_user_window_content()
        ut.close_add_AD_user_window()

    # @pytest.mark.develop
    def test_add_user_window_close_buttons(self, browser: Page) -> None:
        """Проверяет кнопки закрытия окна добавления.

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

        ut = UsersTab(browser)
        browser.wait_for_timeout(500)
        
        ut.open_add_user_window()
        ut.close_add_user_window_by_toolbar_button()

        ut.open_add_user_window()
        ut.close_add_user_window()

        ut.open_add_user_window()
        ut.transform_to_add_AD_user_window()
        ut.close_add_AD_user_window_by_toolbar_button()

        ut.open_add_user_window()
        ut.transform_to_add_AD_user_window()
        ut.close_add_AD_user_window()

    # @pytest.mark.develop
    def test_add_local_user(self, browser: Page, cleanup_users: None) -> None:
        """Проверяет добавление локального пользователя.

        Args:
            browser: Экземпляр страницы Playwright.
            cleanup_users: Фикстура для автоматического удаления пользователя после теста.
        """

        user_data: Dict[str, str] = {"name": "TestUser", "role": "Администратор", "password": "987654321abcd"}
        self._add_user(browser, user_data)

    # @pytest.mark.develop
    def test_add_AD_user(self, browser: Page, cleanup_users: None) -> None:
        """Проверяет добавление пользователя Active Directory.

        Args:
            browser: Экземпляр страницы Playwright.
            cleanup_users: Фикстура для автоматического удаления пользователя после теста.
        """

        user_data: Dict[str, str] = {
                    "auth_type": "active_directory",
                    "group": "NMS_tester",
                    "name_AD": "tester1",  # Выбор из списка "Пользователи AD"
                    "name": "TestUserAD",  # Ручной ввод в поле "Имя"
                    "role": "Администратор"
        }
        self._add_user(browser, user_data)

    def _add_user(self, browser: Page, user_data: Dict[str, str]) -> None:
        """Действия при добавлении пользователя.

        Args:
            browser: Экземпляр страницы Playwright.
            user_data: Список полей для заполнения формы создания пользователя.
        """

        ut = UsersTab(browser)

        # Проверяем, есть ли такой пользователь
        user_exists = ut.find_user_in_table(user_data["name"], user_data["role"]) != -1

        if not user_exists:
            # Создаем пользователя впервые
            ut.open_add_user_window()
            
            if ut.add_new_user(user_data):
                # Ждем обновления таблицы с использованием ожиданий Playwright
                browser.wait_for_timeout(2000)

                # Проверяем наличие пользователя в таблице
                user_found = ut.find_user_in_table(user_data["name"], user_data["role"]) != -1
                if not user_found:
                    # Если пользователь не найден, обновляем страницу
                    browser.reload()
                    browser.wait_for_timeout(2000)
            else:
                ut.close_add_user_window()

        # Пытаемся создать такого же пользователя снова
        ut.open_add_user_window()
        success_second = ut.add_new_user(user_data)

        # Должно вернуться False при попытке создания существующего пользователя
        assert not success_second, "Ожидалась ошибка при создании существующего пользователя"
