"""Модуль modal_add_local_user содержит класс для работы
с модальным окном добавления локального пользователя.

Класс AddLocalUserModalWindow наследует базовый функционал ModalWindowComponent
и реализует специфичные методы для работы с формами добавления пользователей.
"""

import re
from playwright.sync_api import Page
from tools.logger import get_logger
from locators.modal_window_locators import ModalWindowLocators
from elements.text_input_element import TextInput
from elements.text_element import Text
from elements.checkbox_element import Checkbox
from components.modal_window_component import ModalWindowComponent
from components.dropdown_list_component import DropdownList
from components.confirm_component import ConfirmComponent
from components_derived.selection_bar_component import SelectionBarComponent

logger = get_logger("ADD_USER_MODAL_WINDOW")

class AddUserModalWindow(ModalWindowComponent):
    """Модальное окно добавления нового пользователя.

    Наследует ModalWindowComponent и добавляет элементы формы:
    - Поля ввода (имя, пароль, email и др.)
    - Чекбоксы (Блокировка, Push-уведомления)
    - Выпадающий список ролей
    - Кнопки действий
    """

    def __init__(self, page: Page):
        """Инициализирует элементы формы добавления пользователя."""

        super().__init__(page)

        # Локаторы элементов формы
        input_form_locator = ModalWindowLocators.INPUT_FORM_USER_DATA

        # Настройка заголовка и кнопки закрытия тулбара
        self.window_title = "Добавить нового пользователя"
        locator_button_toolbar_close = (
            self.page.get_by_role("navigation")
            .filter(has_text=re.compile(self.window_title))
            .get_by_role("button")
        )

        self.add_toolbar_title(self.window_title)
        self.add_toolbar_button(locator_button_toolbar_close, "close")

        elements_locators = self.get_input_fields_locators(page.locator(input_form_locator))
        # print(elements_locators)

        # Поле Тип авторизации
        auth_type_loc = elements_locators.get("Тип авторизации")
        if auth_type_loc:
            auth_type_selector = SelectionBarComponent(page, auth_type_loc.get_by_role("combobox").first)
            self.add_content_item("auth_type_selector", auth_type_selector)

        # Поле Имя
        loc = elements_locators.get("Имя").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_NAME)
        name_input = TextInput(page, loc, "name_input")
        self.add_content_item("name_input", name_input)

        # Метка "Блокировка"
        label_blocking_locator = self.page.locator(input_form_locator). \
                                 locator("//label").get_by_text("Блокировка")
        label_blocking = Text(
            page,
            label_blocking_locator,
            "blocking_checkbox_label"
        )

        self.add_content_item("blocking_checkbox_label", label_blocking)

        # Чекбокс "Блокировка"
        checkbox_blocking = Checkbox(
            page,
            page.locator(input_form_locator).locator(ModalWindowLocators.INPUT_FORM_USER_DATA_CHECKBOX_BLOCKED),
            "blocking"
        )
        self.add_content_item("blocking_checkbox", checkbox_blocking)

        # Поле Роль
        role_loc = elements_locators.get("Роль").get_by_role("combobox").first
        role_input = TextInput(page, role_loc, "role_input")
        self.add_content_item("role_input", role_input)
        self.add_content_item("roles_list", DropdownList(page))

        # Поле Пароль
        loc = elements_locators.get("Пароль").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_PASSWORD)
        password_input = TextInput(page, loc, "password_input")
        self.add_content_item("password_input", password_input)

        # Поле Комментарий
        loc = elements_locators.get("Комментарий").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_COMMENT)
        commentary_input = TextInput(page, loc, "commentary_input")
        self.add_content_item("commentary_input", commentary_input)

        # Поле E-mail
        loc = elements_locators.get("E-mail").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_EMAIL)
        email_input = TextInput(page, loc, "email_input")
        self.add_content_item("email_input", email_input)

        # Поле Номер для СМС
        loc = elements_locators.get("Номер для СМС").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_SMS)
        phone_input = TextInput(page, loc, "phone_input")
        self.add_content_item("phone_input", phone_input)

        # Метка "Подписка на Push-уведомления"
        label_push_locator = self.page.locator(input_form_locator). \
                            locator("//label").get_by_text("Подписка на Push-уведомления")
        label_push = Text(
            page,
            label_push_locator,
            "push_notification_checkbox_label"
        )
        self.add_content_item("push_notification_checkbox_label", label_push)

        # Чекбокс "Подписка на Push-уведомления"
        checkbox_push = Checkbox(
            page,
            page.locator(input_form_locator).locator(ModalWindowLocators.INPUT_FORM_USER_DATA_CHECKBOX_PUSH_ACTIVE),
            "push_notification"
        )
        self.add_content_item("push_notification_checkbox", checkbox_push)

        # Добавление кнопок действий
        locator_button_add = self.page.get_by_role("button", name="Добавить")
        self.add_button(locator_button_add, "add")

        locator_button_close = self.page.get_by_role("button", name="Закрыть")
        self.add_button(locator_button_close, "close")

        # Добавление компонента подтверждения/отмены заведения пользователя
        self.new_user_confirm = ConfirmComponent(page, " Отмена ", " Добавить ")

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

        self.get_content_item("blocking_checkbox").check(force=True)

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

        self.get_content_item("blocking_checkbox").uncheck(force=True)

    def check_push_notification_checkbox(self):
        """Включает чек-бокс Push-уведомления."""

        self.get_content_item("push_notification_checkbox").check(force=True)

    def uncheck_push_notification_checkbox(self):
        """Выключает чек-бокс Push-уведомления."""

        self.get_content_item("push_notification_checkbox").uncheck(force=True)

    def get_auth_type(self) -> str | None:
        """Возвращает текущее значение поля 'Тип авторизации'"""

        auth_type = None
        auth_type_selector = self.get_content_item("auth_type_selector")
        if auth_type_selector:
            values =  auth_type_selector.get_selected_values()
            auth_type = values[0]
        return auth_type

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

        auth_type_selector = self.get_content_item("auth_type_selector")
        if auth_type_selector:
            auth_type_selector.open_values_list()
            auth_type_selector.select_value(auth_type)

    def new_user(self, user_data):
        """Заполняет форму и добавляет нового пользователя.

        Args:
            user_data (dict): Данные пользователя (имя, роль, пароль и др.)
        """

        auth_type = user_data.get("auth_type")
        if auth_type is None:
            auth_type = 'local'

        current_auth_type = self.get_auth_type()
        if current_auth_type != auth_type:
            self.select_auth_type(auth_type)

        if auth_type == "LDAP":
            menu_locator = self.page.locator(ModalWindowLocators.MENU_ACTIVE_INPUT_FORM)

            elements_locators = self.get_input_fields_locators(
                                self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))

            # Добавилось поле Группа
            group_loc = elements_locators.get("Группа").get_by_role("combobox")
            group_input = TextInput(self.page, group_loc, "group_input")
            self.add_content_item("group_input", group_input)
            self.add_content_item("group_list", DropdownList(self.page))

            # Добавилась кнопка Поиск
            locator_button_search = self.page.get_by_role("button", name="Поиск")
            self.add_button(locator_button_search, "search")

            # Поиск и выбор заданной группы из списка существующих
            group_field = self.get_content_item("group_input")
            group_field.click()

            group_name = user_data["group"]
            group_list = self.get_content_item("group_list")
            group_list.scroll_until_end(menu_locator)
            group_names = group_list.get_item_names(menu_locator)
            if group_name not in group_names:
                assert False, f"Required group name {group_name} is missing"

            group_list.check_item_with_text(group_name)
            group_list.click_item_with_text(group_name)

            # Нажатие кнопки "Поиск"
            search_button = self.get_button_by_name("search")
            search_button.click()

            # Если в группе есть пользователи, открывается новое поле, заново вычисляем локаторы
            elements_locators = self.get_input_fields_locators(
                                self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))
            users_ad_loc = elements_locators.get("Пользователи AD")
            # users_ad_loc = elements_locators.get("Пользователи LDAP")
            assert users_ad_loc, f"Selected group {group_name} is empty. Use another group."

            # Поиск и выбор заданного пользователя AD из списка существующих
            user_ldap_loc = users_ad_loc.get_by_role("combobox")
            user_ldap_input = TextInput(self.page, user_ldap_loc, "user__input")
            self.add_content_item("user_ldap_input", user_ldap_input)
            self.add_content_item(
                "user_ldap_list",
                DropdownList(self.page)
            )

            user_ldap_input.click()
            user_ldap_list = self.get_content_item("user_ldap_list")
            user_ldap_list.scroll_until_end(menu_locator)
            user_ldap_names = group_list.get_item_names(menu_locator)
            name_ldap = user_data.get("name_ldap")
            if name_ldap not in user_ldap_names:
                assert False, f"Required user name {name_ldap} is missing"

            user_ldap_list.check_item_with_text(name_ldap)
            user_ldap_list.click_item_with_text(name_ldap)

            # Заново вычисляем локаторы полей ввода
            self.locators_recalculation(is_active_directory=True)

        # Заполнение поля "Имя" (ручной ввод) если задано
        name = user_data.get("name")
        if name:
            input_field = self.get_content_item("name_input")
            input_field.input_value(name)

        fields = user_data.keys()

        if "role" in fields:
            role_field = self.get_content_item("role_input")
            role_field.click()

            roles_list = self.get_content_item("roles_list")
            roles_list.check_item_with_text(user_data["role"])
            roles_list.click_item_with_text(user_data["role"])

        if "password" in fields:
            input_field = self.get_content_item("password_input")
            input_field.input_value(user_data["password"])

        if "commentary" in fields:
            input_field = self.get_content_item("commentary_input")
            input_field.input_value(user_data["commentary"])

        if "email" in fields:
            input_field = self.get_content_item("email_input")
            input_field.input_value(user_data["email"])

        if "phone_number" in fields:
            input_field = self.get_content_item("phone_input")
            input_field.input_value(user_data["phone_number"])

        if "blocking_checked" in fields:
            checkbox = self.get_content_item("blocking_checkbox")
            if user_data["blocking_checked"]:
                checkbox.check()
            else:
                checkbox.uncheck()

        if "push_notification_checked" in fields:
            checkbox = self.get_content_item("push_notification_checkbox")
            if user_data["push_notification_checked"]:
                checkbox.check()
            else:
                checkbox.uncheck()

        # Отправка формы
        add_button = self.get_button_by_name("add")
        add_button.click()

        # Подтверждение действия
        title = "Добавить нового пользователя"
        self.new_user_confirm.check_title(
            title,
            f"Confirmation dialog window with title '{title}' is missing"
        )
        self.new_user_confirm.click_allow_button()

    def close_window(self):
        """Закрывает модальное окно через кнопку 'Закрыть'."""

        close_button = self.get_button_by_name("close")
        close_button.click()

    def close_window_by_toolbar_button(self):
        """Закрывает модальное окно через кнопку в тулбаре."""

        self.click_toolbar_close_button()

    def locators_recalculation(self, is_active_directory=False) -> None:
        """Пересчет локаторов полей ввода"""

        elements_locators = self.get_input_fields_locators(
                            self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))

        new_loc = elements_locators.get("Имя").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_NAME)
        self.get_content_item("name_input").update_locator(new_loc)

        if not is_active_directory:
            new_loc = elements_locators.get("Пароль").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_PASSWORD)
            self.get_content_item("password_input").update_locator(new_loc)

        new_loc = elements_locators.get("Роль").get_by_role("combobox").first
        self.get_content_item("role_input").update_locator(new_loc)

        new_loc = elements_locators.get("Комментарий").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_COMMENT)
        self.get_content_item("commentary_input").update_locator(new_loc)

        new_loc = elements_locators.get("E-mail").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_EMAIL)
        self.get_content_item("email_input").update_locator(new_loc)

        new_loc = elements_locators.get("Номер для СМС").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_SMS)
        self.get_content_item("phone_input").update_locator(new_loc)

    # Проверки:
    def check_content(self):
        """Проверяет наличие и корректность всех элементов формы создания локального пользователя.
           Форма для создания keycloack пользователя имеет тот же набор полей.
        """

        expected_auth_types = ['local', 'LDAP', 'keycloak']
        expected_roles = ['$collector', 'Администратор',
                          'Специалист информационной безопасности',
                          'Контактное лицо', 'Оператор']

        menu_locator = self.page.locator(ModalWindowLocators.MENU_ACTIVE_INPUT_FORM)

        self.check_by_window_title()

        self.check_toolbar_button_visibility("close")
        self.check_toolbar_button_tooltip("close", "Закрыть")

        input_fields = ["name_input", "password_input",
                        "commentary_input", "email_input", "phone_input"]

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

            if name == "blocking_checkbox_label":
                item.check_have_text(
                    "Блокировка",
                    "Label 'Блокировка' is missing"
                )
            elif name == "push_notification_checkbox_label":
                item.check_have_text(
                    "Подписка на Push-уведомления",
                    "Label 'Подписка на Push-уведомления' is missing"
                )
            elif name == "auth_type_selector":
                current_auth_type = self.get_auth_type()
                if current_auth_type is None:
                    continue
                assert current_auth_type == 'local', "Default Auth Type value should be 'local'"

                actual_auth_types = item.get_available_options()
                assert actual_auth_types == expected_auth_types, \
                       f"Actual auth types {actual_auth_types} are not equal expected values {expected_auth_types}."
            elif name == "role_input":
                item.click()
                roles_list = self.get_content_item("roles_list")
                roles_list.check_visibility(menu_locator, "Roles list is missing")

                is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator)
                assert not is_scrollable_vertically, (
                    "Roles list should not be scrollable_vertically"
                )

                for role in expected_roles:
                    roles_list.check_item_with_text(role)
            elif name in input_fields:
                item.check_editable_input(
                    f"Input field with name '{name}' should be editable"
                    )
            elif name == "roles_list":
                continue
            else:
                # print(f"check item: {name}")
                # print(item)
                item.check_visibility(
                    f"Modal window content item with name '{name}' is missing"
                )

        # Дополнительная проверка состояния чекбоксов
        blocking_checkbox = self.get_content_item("blocking_checkbox")
        is_blocking_checked = blocking_checkbox.is_checked()
        assert not is_blocking_checked, (
            "Checkbox 'Блокировка' should not be checked by default"
        )

        push_checkbox = self.get_content_item("push_notification_checkbox")
        is_push_checked = push_checkbox.is_checked()
        assert not is_push_checked, (
            "Checkbox 'Подписка на Push-уведомления' should not be checked by default"
        )

        # Выбор типа авторизации LDAP и проверка появления поля Группа и кнопки Поиск
        auth_type_selector = self.get_content_item("auth_type_selector")
        if auth_type_selector:
            self.select_auth_type("LDAP")

            elements_locators = self.get_input_fields_locators(
                                self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))

            # Добавилось поле Группа
            group_loc = elements_locators.get("Группа").get_by_role("combobox")
            group_input = TextInput(self.page, group_loc, "group_input")
            self.add_content_item("group_input", group_input)
            self.add_content_item("group_list", DropdownList(self.page))

            group_field = self.get_content_item("group_input")
            group_field.click()

            group_list = self.get_content_item("group_list")
            group_list.check_visibility(menu_locator,
                                      "Groups list is missing")

            is_scrollable_vertically = group_list.check_vertical_scrolling(menu_locator)
            assert is_scrollable_vertically, "Groups list should be scrollable_vertically"
            self.page.keyboard.press("Escape")

            # Добавилась кнопка Поиск
            locator_button_search = self.page.get_by_role("button", name="Поиск")
            self.add_button(locator_button_search, "search")
            self.check_button_visibility("search")

        self.check_button_visibility("add")
        self.check_button_visibility("close")
