"""Модуль тестов карточки пользователя.

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

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

user_data = {"name": "TestUserForChangePwd", "role": "Администратор", "password": "qwerty1234567", "new_password": "ytrewq7654321"}

# @pytest.mark.smoke
class TestUserCard:
    """Класс тестов для проверки карточки пользователя.

    Тесты покрывают следующие сценарии:
    1. test_user_card_content: Проверяет содержимое карточки пользователя
    2. test_logout_button: Проверяет выход из приложения при нажатии кнопки 'Выйти' и переход на страницу login
    3. test_close_button: Проверяет закрытие карточки пользователя при нажатии на кнопку 'Закрыть'
    4. test_change_password_window_content: Проверяет наличие и корректность элементов окна изменения пароля текущего пользователя
    5. test_change_password_successful: Проверяет успешное изменение пароля текущего пользователя
    6. test_change_password_unsuccessful: Проверяет неуспешное изменение пароля текущего пользователя

    Атрибуты:
        browser: Фикстура для работы с браузером.
    """

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

        lp = LoginPage(browser)
        lp.do_login()

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

        # Создание нового пользователя
        mp.click_main_navigation_panel_item("Настройки")
        mp.click_subpanel_item("Пользователи")
        browser.wait_for_timeout(500)

        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"])

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

        yield

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

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

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

        # Удаляем пользователя
        mp_admin = MainPage(browser)
        mp_admin.click_main_navigation_panel_item("Настройки")
        mp_admin.click_subpanel_item("Пользователи")

        ut = UsersTab(browser)
        ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
        ut.delete_user(user_data["name"])

    # @pytest.mark.develop
    def test_user_card_content(self, browser: Page) -> None:
        """Проверяет наличие и корректность элементов карточки пользователя.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)

        user_card = mp.click_user_button()
        user_card.check_content()

    # @pytest.mark.develop
    def test_logout_button(self, browser: Page) -> None:
        """Проверяет выход из приложения при нажатии кнопки 'Выйти' и переход на страницу login.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)

        user_card = mp.click_user_button()
        mp.wait_for_timeout(300)

        user_card.click_logout_button()

        new_lp = LoginPage(browser)
        new_lp.check_URL('login', "Login page should be opened")

    # @pytest.mark.develop
    def test_close_button(self, browser: Page) -> None:
        """Проверяет закрытие карточки пользователя при нажатии на кнопку 'Закрыть'.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)

        user_card = mp.click_user_button()
        mp.wait_for_timeout(300)

        user_card.click_close_button()
        user_card.check_card_is_closed()

    def test_change_password_window_content(self, browser: Page) -> None:
        """Проверяет наличие и корректность элементов окна изменения пароля текущего пользователя.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)

        user_card = mp.click_user_button()
        change_password_window = user_card.click_change_password_button()
        change_password_window.check_content()

    def test_change_password_successful(self, browser: Page,
                                           create_user: None,
                                           cleanup_user: None) -> None:
        """Проверяет успешное изменение пароля текущего пользователя.

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

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

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

        user_card = mp.click_user_button()
        change_password_window = user_card.click_change_password_button()
        is_changed, error = change_password_window.change_password(user_data["password"], user_data["new_password"])
        assert is_changed, f"Unsucessful attempt to change password: {error}"

    def test_change_password_unsuccessful(self, browser: Page,
                                           create_user: None,
                                           cleanup_user: None) -> None:
        """Проверяет неуспешное изменение пароля текущего пользователя.

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

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

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

        # Значение полей нового пароля и подтверждения нового пароля не совпадают
        user_card = mp.click_user_button()
        change_password_window = user_card.click_change_password_button()
        password_inputs = change_password_window.get_password_inputs()

        password_inputs[0].input_value(user_data["password"])
        password_inputs[1].input_value(user_data["new_password"])
        password_inputs[2].input_value("12345")

        change_password_window.check_error_message("Пароли не совпадают")
        change_password_window.click_cancel_button()

        # Используется неправильный старый пароль
        user_card = mp.click_user_button()
        change_password_window = user_card.click_change_password_button()
        is_changed, _ = change_password_window.change_password("123456789123", user_data["new_password"])
        assert not is_changed, "Sucessful attempt to change password for incorrect old password"
        change_password_window.click_cancel_button()

        # Пустое поле ввода пароля на примере поля ввода старого пароля
        user_card = mp.click_user_button()
        change_password_window = user_card.click_change_password_button()
        is_changed, error = change_password_window.change_password("", user_data["new_password"])
        assert not is_changed, "Sucessful attempt to change password for empty old password input"
        err_message = "Это поле обязательно для заполнения"
        assert error != err_message, f"Expected error message '{err_message}' is not equal '{error}'"
        change_password_window.click_cancel_button()
