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

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

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 components.toolbar_component import ToolbarComponent
from components.alert_component import AlertComponent
from components_derived.settings_form_component import SettingsFormComponent
from pages.base_page import BasePage


class SessionSettingsTab(BasePage):
    """Класс для работы с вкладкой 'Сеансы/Настройки'.

    Предоставляет методы для взаимодействия с полями настройки сессий пользователей.

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

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

        super().__init__(page)

        locator_button_1 = self.page.get_by_role("navigation").filter(
            has_text=re.compile("Настройки")
        ).get_by_role("button").nth(0)
        locator_button_2 = self.page.get_by_role("navigation").filter(
            has_text=re.compile("Настройки")
        ).get_by_role("button").nth(1)

        self.toolbar = ToolbarComponent(page, "Настройки")
        self.toolbar.add_tooltip_button(locator_button_1, "edit")
        self.toolbar.add_tooltip_button(locator_button_1, "save")
        self.toolbar.add_tooltip_button(locator_button_2, "cancel")

        # Форма для отображения/редактирования полей настроек сессии пользователя
        self.settings_form = SettingsFormComponent(page)

        self.settings_form.add_toolbar_title("Время жизни сеанса")

        admin_setting_label = Text(page,
                                   page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                   get_by_text('Администратор'),
                                   "admin_setting_label")
        self.settings_form.add_content_item("admin_setting_label", admin_setting_label)

        loc_admin = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
             get_by_label('Администратор')
        admin_setting = TextInput(page, loc_admin, "admin_setting")
        self.settings_form.add_content_item("admin_setting", admin_setting)

        operator_setting_label = Text(page,
                                   page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                   get_by_text('Оператор'),
                                   "operator_setting_label")
        self.settings_form.add_content_item("operator_setting_label", operator_setting_label)

        loc_oper = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
            get_by_label('Оператор')
        operator_setting = TextInput(page, loc_oper, "operator_setting")
        self.settings_form.add_content_item("operator_setting", operator_setting)

        manager_setting_label = Text(page,
                                   page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                   get_by_text('Контактное лицо'),
                                   "manager_setting_label")
        self.settings_form.add_content_item("manager_setting_label", manager_setting_label)

        loc_manager = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
            get_by_label('Контактное лицо')
        manager_setting = TextInput(page, loc_manager, "manager_setting")
        self.settings_form.add_content_item("manager_setting", manager_setting)

        inform_secur_user_setting_label = Text(page,
                                   page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                   get_by_text('Специалист информационной безопасности'),
                                   "inform_secur_user_setting_label")
        self.settings_form.add_content_item("inform_secur_user_setting_label", inform_secur_user_setting_label)

        loc_inform_secur_user = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
            get_by_label('Специалист информационной безопасности')
        inform_secur_user_setting = TextInput(page, loc_inform_secur_user, "inform_secur_user_setting")
        self.settings_form.add_content_item("inform_secur_user_setting", inform_secur_user_setting)

        collector_setting_label = Text(page,
                                   page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
                                   get_by_text('$collector'),
                                   "collector_setting_label")
        self.settings_form.add_content_item("collector_setting_label", collector_setting_label)

        loc_collector = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
            get_by_label('$collector')
        collector_setting = TextInput(page, loc_collector, "collector_setting")
        self.settings_form.add_content_item("collector_setting", collector_setting)

        # Окно сообщения об успешном/неуспешном сохранении настроек
        self.alert = AlertComponent(page)

    # Действия:
    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 decrease_setting_value(self, field_name: str) -> None:
        """Уменьшение на единицу значения поля настройки с помощью стрелочки вниз."""

        field = self.get_field_by_name(field_name)
        field.decrease_value()

    def increase_setting_value(self, field_name: str) -> None:
        """Увеличение на единицу значения поля настройки с помощью стрелочки вверх."""

        field = self.get_field_by_name(field_name)
        field.increase_value()

    def get_field_by_name(self, field_name: str) -> TextInput:
        """Возвращает элемент поле ввода по его имени.

        Returns:
            TextInput: Элемент поле ввода.
        """

        if field_name == "administrator":
            field = self.settings_form.get_content_item("admin_setting")
        elif field_name == "operator":
            field = self.settings_form.get_content_item("operator_setting")
        elif field_name == "manager":
            field = self.settings_form.get_content_item("manager_setting")
        elif field_name == "inform_secur_user":
            field = self.settings_form.get_content_item("inform_secur_user_setting")
        elif field_name == '$collector':
            field = self.settings_form.get_content_item("collector_setting")
        else:
            assert False, f"Got unsupported field name {field_name}"
        return field

    def get_label_by_name(self, label_name: str) -> Text:
        """Возвращает элемент название поля ввода по его имени.

        Returns:
            Text: Элемент название поле ввода.
        """

        if label_name == "administrator":
            label = self.settings_form.get_content_item("admin_setting_label")
        elif label_name == "operator":
            label = self.settings_form.get_content_item("operator_setting_label")
        elif label_name == "manager":
            label = self.settings_form.get_content_item("manager_setting_label")
        elif label_name == "inform_secur_user":
            label = self.settings_form.get_content_item("inform_secur_user_setting_label")
        elif label_name == '$collector':
            label = self.settings_form.get_content_item("collector_setting_label")
        else:
            assert False, f"Got unsupported label name {label_name}"
        return label

    def get_setting_value(self, field_name: str) -> str:
        """Возвращает текущее значение требуемого поля настроек.

        Returns:
           str : Текущее значение требуемого поля настроек.
        """

        return self.get_field_by_name(field_name).get_input_value().strip()

    def get_settings_values(self) -> dict:
        """Возвращает словарь с текущими значениями настроек времени жизни сессии.

        Returns:
            dict: Cловарь с текущими значениями настроек времени жизни сессии.
        """

        current_values = {}

        current_values['administrator'] = self.settings_form.get_content_item("admin_setting").\
                                          get_input_value().strip()
        current_values['operator'] = self.settings_form.get_content_item("operator_setting").\
                                          get_input_value().strip()
        current_values['manager'] = self.settings_form.get_content_item("manager_setting").\
                                          get_input_value().strip()
        current_values['inform_secur_user'] = self.settings_form.get_content_item("inform_secur_user_setting").\
                                          get_input_value().strip()
        current_values['$collector'] = self.settings_form.get_content_item("collector_setting").\
                                          get_input_value().strip()
        return current_values

    def edit_settings(self, new_settings: dict) -> None:
        """Изменение текущих значений настроек времени жизни сессии.
        """

        self.click_edit_button()

        for key, value in new_settings.items():
            field = self.get_field_by_name(key)
            field.input_value(value)

        # temporararily
        self.click_cancel_button()

        # self.click_save_button()

        # alert_type = self.alert.get_alert_type()
        # if alert_type == "success":
        #     self.alert.check_alert_presence(' Параметры успешно\n обновлены ')
        #     self.alert.check_alert_absence(' Параметры успешно\n обновлены ')
        # else:
        #     assert False, f"Got unexpected alert type {alert_type}"

    def scroll_down(self) -> None:
        """Скроллинг вниз формы настроек времени жизни сессии.
        """

        locator = self.page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).filter(
                  has_text="Время жизни сеанса")
        self.settings_form.scroll_down(locator)

    def scroll_up(self) -> None:
        """Скроллинг вверх формы настроек времени жизни сессии.
        """

        locator = self.page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).filter(
                  has_text="Время жизни сеанса")
        self.settings_form.scroll_up(locator)

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

        self.should_be_toolbar()
        self.should_be_toolbar_buttons()

        self.should_be_form_toolbar()

        for name in self.settings_form.content_items.keys():
            item = self.settings_form.get_content_item(name)
            item.check_visibility(
                f"Session settings input form item with name '{name}' is missing"
            )

    def check_vertical_scrolling(self) -> bool:
        """Проверка возможности вертикального скроллинга формы настроек времени жизни сессии.
        """

        locator = self.page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).filter(
                  has_text="Время жизни сеанса")
        return self.settings_form.check_vertical_scrolling(locator)

    def should_be_toolbar(self) -> None:
        """Проверяет наличие тулбара вкладки.

        Raises:
            AssertionError: Если тулбар или кнопка редактирования отсутствуют.
        """
        loc = self.page.get_by_role("navigation").filter(
              has_text=re.compile("Настройки")).locator("div").nth(1)
        self.toolbar.check_toolbar_presence_by_locator(loc, "Toolbar with title 'Настройки' is missing")
        self.toolbar.check_button_visibility("edit")

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

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

        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_form_toolbar(self) -> None:
        """Проверяет наличие тулбара формы редактирования настроек.

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

        self.settings_form.should_be_toolbar()

    def verify_form_data(self, session_settings: dict) -> None:
        """Проверяет соответствие содержимого полей формы данным из БД.

        Raises:
            AssertionError: Если содержимое поля не соответствует данным из БД.
        """

        for key, value in session_settings.items():
            field_value = ""
            if key == "administrator":
                field_value = self.settings_form.get_content_item("admin_setting").get_input_value().strip()
            elif key == "operator":
                field_value = self.settings_form.get_content_item("operator_setting").get_input_value().strip()
            elif key == "manager":
                field_value = self.settings_form.get_content_item("manager_setting").get_input_value().strip()
            elif key == "inform_secur_user":
                field_value = self.settings_form.get_content_item("inform_secur_user_setting").get_input_value().strip()
            elif key == '$collector':
                field_value = self.settings_form.get_content_item("collector_setting").get_input_value().strip()
            else:
                assert False, f"Got unsupported field name {key}"
            assert field_value == str(value), f"{key} field value {field_value} is not equal value {value} from data base"
