"""Модуль вкладки настройки E-mail уведомлений.

Содержит класс SMSNotificationsSettings для работы с вкладкой настройки E-mail уведомлений.
Позволяет проверять состояние и взаимодействовать с элементами вкладки.
"""

import re
from playwright.sync_api import Page
from locators.settings_form_locators import SettingsFormLocators
from elements.text_input_element import TextInput
from elements.text_element import Text
from elements.tooltip_button_element import TooltipButton
from elements.checkbox_element import Checkbox
from components.toolbar_component import ToolbarComponent
from components.alert_component import AlertComponent
from components_derived.settings_form_component import SettingsFormComponent
from components_derived.selection_bar_component import SelectionBarComponent
from components_derived.modal_send_test_email import SendTestEmailModalWindow
from pages.base_page import BasePage


class EmailNotificationsSettingsTab(BasePage):
    """Класс для работы с вкладкой настройки E-mail уведомлений.

    Предоставляет методы для взаимодействия с вкладкой настройки E-mail уведомлений.

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

    def __init__(self, page: Page) -> None:
        """Инициализирует компоненты вкладки настройки E-mail уведомлений."""

        super().__init__(page)

        self.toolbar = ToolbarComponent(page, "e-mail")

        toolbar_button_edit = self.page.get_by_role("navigation").filter(has_text=re.compile("e-mail")). \
                                        locator("//button[@data-testid='NOTIFICATIONS_SMTP__btn__edit']")
        self.toolbar.add_tooltip_button(toolbar_button_edit, "edit")

        toolbar_button_save = self.page.get_by_role("navigation").filter(has_text=re.compile("e-mail")). \
                                        locator("//button[@data-testid='NOTIFICATIONS_SMTP__btn__submit']")
        self.toolbar.add_tooltip_button(toolbar_button_save, "save")

        toolbar_button_cancel = self.page.get_by_role("navigation").filter(has_text=re.compile("e-mail")). \
                                          locator("//button[@data-testid='NOTIFICATIONS_SMTP__btn__cancelEdit']")
        self.toolbar.add_tooltip_button(toolbar_button_cancel, "cancel")

        # Форма для отображения/редактирования общих полей настроек
        self.common_settings = SettingsFormComponent(page)
        self.common_settings.add_toolbar_title(" Общие ")

        container_locator = self.page.locator("//nav[contains(@class, 'active v-toolbar')]"). \
                            filter(has_text=" Общие ").locator("//following-sibling::div")
        self.common_input_fields_locators = self.common_settings.get_input_fields_locators(container_locator)

        loc = self.common_input_fields_locators.get("Сервер")
        loc_server_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__common_text-field__smtp_host']")
        server_setting_input = TextInput(page, loc_server_input, "server_setting_input")
        self.common_settings.add_content_item("server_setting_input", server_setting_input)

        loc = self.common_input_fields_locators.get("Порт")
        loc_port_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__common_text-field__smtp_port']")
        port_setting_input = TextInput(page, loc_port_input, "port_setting_input")
        self.common_settings.add_content_item("port_setting_input", port_setting_input)

        loc = self.common_input_fields_locators.get("Отправитель")
        loc_sender_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__common_text-field__from_email']")
        sender_setting_input = TextInput(page, loc_sender_input, "sender_setting_input")
        self.common_settings.add_content_item("sender_setting_input", sender_setting_input)

        field_locator = container_locator.locator("//div[@data-testid='NOTIFICATIONS_SMTP__common_checkbox__active']")
        # Метка "Активировать"
        label_activate_locator = field_locator.locator("//label").get_by_text("Активировать")
        label_activate = Text(page, label_activate_locator, "checkbox_activate_label")
        self.common_settings.add_content_item("checkbox_activate_label", label_activate)

        # Чекбокс "Активировать"
        checkbox_activate = Checkbox(page,
            field_locator.locator("//input[@data-testid='NOTIFICATIONS_SMTP__common_checkbox__active']"),
            "activate"
        )
        self.common_settings.add_content_item("checkbox_activate", checkbox_activate)

        # Форма для отображения/редактирования общих настроек TLS
        self.tls_settings = SettingsFormComponent(page)
        self.tls_settings.add_toolbar_title(" TLS ")

        container_locator = self.page.locator("//nav[contains(@class, 'active v-toolbar')]"). \
                            filter(has_text=" TLS ").locator("//following-sibling::div")
        self.tls_input_fields_locators = self.tls_settings.get_input_fields_locators(container_locator)

        loc = self.tls_input_fields_locators.get("Использовать TLS-туннель")
        self.tls_settings.add_content_item("tunnel_setting_selector", SelectionBarComponent(page, loc))

        field_locator = container_locator. \
                        locator("//div[@data-testid='NOTIFICATIONS_SMTP__TLS_checkbox__reject_unauthorized']")

        # Метка "Принимать самоподписанные сертификаты"
        label_accept_certificates_locator = field_locator. \
                                            locator("//label").get_by_text("Принимать самоподписанные сертификаты")
        label_accept_certificates = Text(page, label_accept_certificates_locator, "checkbox_accept_certificates_label")
        self.tls_settings.add_content_item("checkbox_accept_certificates_label", label_accept_certificates)

        # Чекбокс "Принимать самоподписанные сертификаты"
        checkbox_accept_certificates = Checkbox(page,
            field_locator.locator("//input[@data-testid='NOTIFICATIONS_SMTP__TLS_checkbox__reject_unauthorized']"),
            "accept_certificates"
        )
        self.tls_settings.add_content_item("checkbox_accept_certificates", checkbox_accept_certificates)

        # Форма для отображения/редактирования полей настроек аутентификации
        self.auth_settings = SettingsFormComponent(page)
        self.auth_settings.add_toolbar_title(" Аутентификация ")

        container_locator = self.page.locator("//nav[contains(@class, 'active v-toolbar')]"). \
                            filter(has_text=" Аутентификация ").locator("//following-sibling::div")
        self.auth_input_fields_locators = self.auth_settings.get_input_fields_locators(container_locator)

        loc = self.auth_input_fields_locators.get("Метод авторизации")
        self.auth_settings.add_content_item("auth_method_setting_selector", SelectionBarComponent(page, loc))

        loc = self.auth_input_fields_locators.get("Имя пользователя")
        loc_user_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__auth_text-field__login']")
        user_setting_input = TextInput(page, loc_user_input, "user_setting_input")
        self.auth_settings.add_content_item("user_setting_input", user_setting_input)

        loc = self.auth_input_fields_locators.get("Пароль")
        loc_password_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__auth_text-field__password']")
        password_setting_input = TextInput(page, loc_password_input, "password_password_input")
        self.auth_settings.add_content_item("password_setting_input", password_setting_input)

        loc = self.auth_input_fields_locators.get("Домен")
        loc_domain_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__auth_text-field__domain']")
        domain_setting_input = TextInput(page, loc_domain_input, "domain_setting_input")
        self.auth_settings.add_content_item("domain_setting_input", domain_setting_input)

        loc = self.auth_input_fields_locators.get("Рабочая станция")
        loc_workstation_input = loc.locator("//input[@data-testid='NOTIFICATIONS_SMTP__auth_text-field__workstation']")
        workstation_setting_input = TextInput(page, loc_workstation_input, "workstation_setting_input")
        self.auth_settings.add_content_item("workstation_setting_input", workstation_setting_input)

        # Кнопка 'Тест'
        self.test_button = TooltipButton(page,
                                         page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                         locator("//button[@data-testid='NOTIFICATIONS_SMTP__common_btn__test']"),
                                         "test_button")

        self.alert = AlertComponent(page)

    # Действия:
    def check_checkbox_activate(self):
        """Включает чек-бокс Активировать."""

        self.common_settings.get_content_item("checkbox_activate").check(force=True)

    def uncheck_checkbox_activate(self):
        """Выключает чек-бокс Активировать."""

        self.common_settings.get_content_item("checkbox_activate").uncheck(force=True)

    def check_checkbox_accept_certificates(self):
        """Включает чек-бокс Принимать самоподписанные сертификаты."""

        self.tls_settings.get_content_item("checkbox_accept_certificates").check(force=True)

    def uncheck_checkbox_accept_certificates(self):
        """Выключает чек-бокс Принимать самоподписанные сертификаты."""

        self.tls_settings.get_content_item("checkbox_accept_certificates").uncheck(force=True)

    def click_cancel_button(self) -> None:
        """Нажатие кнопки 'Отменить' на тулбаре."""

        self.toolbar.check_button_visibility("cancel")
        self.toolbar.get_button_by_name("cancel").click()

    def click_edit_button(self) -> None:
        """Нажатие кнопки 'Редактировать' на тулбаре."""

        self.toolbar.check_button_visibility("edit")
        self.toolbar.get_button_by_name("edit").click()

    def click_save_button(self) -> None:
        """Нажатие кнопки 'Сохранить' на тулбаре."""

        self.toolbar.check_button_visibility("save")
        self.toolbar.get_button_by_name("save").click()

    def click_test_button(self) -> SendTestEmailModalWindow:
        """Нажатие кнопки 'Тест' в форме ввода настроек."""

        self.should_be_test_button()
        self.test_button.click()
        return SendTestEmailModalWindow(self.page)

    def clear_auth_method_settings(self) -> None:
        """Удаление ранее выбранных значений"""

        auth_method_selector = self.auth_settings.get_content_item("auth_method_setting_selector")
        auth_method_selector.clear_selections()

    def clear_tls_tunnel_settings(self) -> None:
        """Удаление ранее выбранных значений"""

        tls_tunnel_selector = self.tls_settings.get_content_item("tunnel_setting_selector")
        tls_tunnel_selector.clear_selections()

    def get_auth_settings_values(self) -> dict:
        """Возвращает текущее значение полей настроек 'Аутентификация'.

        Returns:
           dict : Текущее значение полей настроек 'Аутентификация'.
        """

        values = {}

        auth_method_selector = self.auth_settings.get_content_item("auth_method_setting_selector")
        if auth_method_selector:
            val =  auth_method_selector.get_selected_values()
            values.update({"Метод авторизации": val[0]})
        else:
            values.update({"Метод авторизации": ""})

        field = self.auth_settings.get_content_item("user_setting_input")
        values.update({"Имя пользователя": field.get_input_value().strip()})

        field = self.auth_settings.get_content_item("password_setting_input")
        values.update({"Пароль": field.get_input_value().strip()})

        field = self.auth_settings.get_content_item("domain_setting_input")
        values.update({"Домен": field.get_input_value().strip()})

        field = self.auth_settings.get_content_item("workstation_setting_input")
        values.update({"Рабочая станция": field.get_input_value().strip()})

        return values

    def get_common_settings_values(self) -> dict:
        """Возвращает текущее значение полей настроек 'Общие'.

        Returns:
           dict : Текущее значение полей настроек 'Общие'.
        """

        values = {}
        field = self.common_settings.get_content_item("server_setting_input")
        values.update({"Сервер": field.get_input_value().strip()})

        field = self.common_settings.get_content_item("port_setting_input")
        values.update({"Порт": field.get_input_value().strip()})

        field = self.common_settings.get_content_item("sender_setting_input")
        values.update({"Отправитель": field.get_input_value().strip()})

        return values

    def get_tls_tunnel_setting_value(self) -> str | None:
        """Возвращает текущее значение поля 'Использовать TLS-туннель'"""

        tls_tunnel_settings = None
        tls_tunnel_selector = self.tls_settings.get_content_item("tunnel_setting_selector")
        if tls_tunnel_selector:
            values =  tls_tunnel_selector.get_selected_values()
            tls_tunnel_settings = values[0]
        return tls_tunnel_settings

    def input_server(self, text: str) -> None:
        """Заполнение поля 'Сервер' настроек 'Общие'."""

        message_input = self.common_settings.get_content_item("server_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_port(self, text: str) -> None:
        """Заполнение поля 'Порт' настроек 'Общие'."""

        message_input = self.common_settings.get_content_item("port_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_sender(self, text: str) -> None:
        """Заполнение поля 'Отправитель' настроек 'Общие'."""

        message_input = self.common_settings.get_content_item("sender_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_user_name(self, text: str) -> None:
        """Заполнение поля 'Имя пользователя' настроек 'Аутентификация'."""

        message_input = self.auth_settings.get_content_item("user_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_password(self, text: str) -> None:
        """Заполнение поля 'Пароль' настроек 'Аутентификация'."""

        message_input = self.auth_settings.get_content_item("password_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_domain(self, text: str) -> None:
        """Заполнение поля 'Домен' настроек 'Аутентификация'."""

        message_input = self.auth_settings.get_content_item("domain_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def input_workstation(self, text: str) -> None:
        """Заполнение поля 'Рабочая станция' настроек 'Аутентификация'."""

        message_input = self.auth_settings.get_content_item("workstation_setting_input")
        message_input.clear()
        message_input.input_value(text)

    def select_auth_method_setting(self, auth_method_setting: str) -> None:
        """Выбирает заданное значение поля 'Метод авторизации' из списка"""

        auth_method_selector = self.auth_settings.get_content_item("auth_method_selector")
        if auth_method_selector:
            auth_method_selector.open_values_list()
            auth_method_selector.select_value(auth_method_setting)

    def select_tls_tunnel_setting(self, tls_tunnel_setting: str) -> None:
        """Выбирает заданное значение поля 'Использовать TLS-туннель' из списка"""

        tls_tunnel_selector = self.tls_settings.get_content_item("tunnel_setting_selector")
        if tls_tunnel_selector:
            tls_tunnel_selector.open_values_list()
            tls_tunnel_selector.select_value(tls_tunnel_setting)

    # Проверки:
    def check_content(self):
        """Проверяет наличие и корректность всех элементов страницы."""

        self.should_be_toolbar()

        self._check_common_settings_content()
        self._check_tls_settings_content()
        self._check_auth_settings_content()

        self.should_be_test_button()
        tooltip_text = self.test_button.get_tooltip_text()
        assert tooltip_text == "Тест", "Should be 'Тест' tooltip for test button"

    def should_be_toolbar(self) -> None:
        """Проверяет наличие тулбара страницы, наличие и функциональность кнопок тулбара.

        Raises:
            AssertionError: Если тулбар или кнопка тулбара отсутствуют.
        """
        loc = self.page.get_by_role("navigation").filter(
              has_text=re.compile("e-mail")).locator("div").nth(1)
        self.toolbar.check_toolbar_presence_by_locator(loc, "Toolbar with title 'E-MAIL' is missing")

        self.toolbar.check_button_visibility("edit")
        self.toolbar.check_button_tooltip("edit", "Редактировать")

        self.toolbar.get_button_by_name("edit").click()
        self.toolbar.check_button_visibility("save")
        self.toolbar.check_button_visibility("cancel")
        self.toolbar.check_button_tooltip("save", "Сохранить")
        self.toolbar.check_button_tooltip("cancel", "Отменить")

        self.toolbar.get_button_by_name("cancel").click()
        self.toolbar.check_button_visibility("edit")

    def should_be_test_button(self) -> None:
        """Проверяет наличие кнопки 'Тест'.

        Raises:
            AssertionError: Если кнопка отсутствует.
        """

        self.test_button.check_visibility("Test button is missing")

    def should_be_success_alert(self) -> None:
        """Проверяет наличие сообщения об успешном обновлении полей настроек .

        Raises:
            AssertionError: Если тулбар отсутствует.
        """

        alert_type = self.alert.get_alert_type()
        assert alert_type == "success", f"Expected success alert, but got {alert_type} alert"

        self.alert.check_alert_presence('\nПараметры успешно\nобновлены\n')
        self.alert.check_alert_absence('\nПараметры успешно\nобновлены\n')

    def _check_common_settings_content(self):
        """Проверяет наличие и корректность всех элементов формы ввода настроек 'Общие'."""

        expected_input_field_names = ["Сервер", "Порт", "Отправитель"]

        self.common_settings.should_be_toolbar()

        actual_input_field_names = self.common_input_fields_locators.keys()
        assert set(actual_input_field_names) == set(expected_input_field_names), \
        f"Misscomparison input field names: Expected {expected_input_field_names}, Actual {actual_input_field_names}"

        for name in self.common_settings.content_items.keys():
            item = self.common_settings.get_content_item(name)
            item.check_visibility(
                f"E-mail notifications Common settings input form item with name '{name}' is missing"
            )

            if name == "checkbox_activate_label":
                item.check_have_text(
                    "Активировать",
                    "Label 'Активировать' is missing"
                )

            if name == "checkbox_activate":
                is_activate_checked = item.is_checked()
                assert not is_activate_checked, (
                    "Checkbox 'Активировать' should not be checked by default"
                )

    def _check_tls_settings_content(self):
        """Проверяет наличие и корректность всех элементов формы ввода настроек 'TLS'."""

        expected_input_field_names = ["Использовать TLS-туннель"]

        self.tls_settings.should_be_toolbar()

        actual_input_field_names = self.tls_input_fields_locators.keys()
        assert set(actual_input_field_names) == set(expected_input_field_names), \
        f"Misscomparison input field names: Expected {expected_input_field_names}, Actual {actual_input_field_names}"

        for name in self.tls_settings.content_items.keys():
            item = self.tls_settings.get_content_item(name)

            if name == "tunnel_setting_selector":
                item.check_field_visibility(
                    f"E-mail notifications TLS settings input form item with name '{name}' is missing"
                )
                item.should_be_clear_selection_button()
                item.should_be_open_list_button()

            if name == "checkbox_accept_certificates_label":
                item.check_visibility(
                    f"E-mail notifications TLS settings input form item with name '{name}' is missing"
                )
                item.check_have_text(
                    "Принимать самоподписанные сертификаты",
                    "Label 'Принимать самоподписанные сертификаты' is missing"
                )

            if name == "checkbox_accept_certificates":
                item.check_visibility(
                    f"E-mail notifications TLS settings input form item with name '{name}' is missing"
                )
                is_accept_certificates_checked = item.is_checked()
                assert is_accept_certificates_checked, (
                    "Checkbox 'Принимать самоподписанные сертификаты' should be checked by default"
                )

    def _check_auth_settings_content(self):
        """Проверяет наличие и корректность всех элементов формы ввода настроек 'Аутентификация'."""

        expected_input_field_names = ["Метод авторизации", "Имя пользователя", "Пароль",
                                      "Домен", "Рабочая станция"]

        self.auth_settings.should_be_toolbar()

        actual_input_field_names = self.auth_input_fields_locators.keys()
        assert set(actual_input_field_names) == set(expected_input_field_names), \
        f"Misscomparison input field names: Expected {expected_input_field_names}, Actual {actual_input_field_names}"

        for name in self.auth_settings.content_items.keys():
            item = self.auth_settings.get_content_item(name)

            if name == "auth_method_setting_selector":
                item.check_field_visibility(
                    f"E-mail notifications Auth settings input form item with name '{name}' is missing"
                )
                item.should_be_clear_selection_button()
                item.should_be_open_list_button()
            else:
                item.check_visibility(
                    f"E-mail notifications Auth settings input form item with name '{name}' is missing"
                )
