"""Модуль тестов компонента средства выбора даты.

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

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


# @pytest.mark.smoke
class TestDatePickerComponent:
    """Класс тестов для проверки компонента средства выбора даты.

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

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

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()
        date_picker.check_content()

    # @pytest.mark.develop
    def test_month_year_selection(self, browser: Page) -> None:
        """Проверяет изменение текущего значения месяца и года с помощью кнопок перехода (стрелочек).

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

        months = ["январь", "февраль", "март", "апрель", "май", "июнь",
                  "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"]

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()

        # Проверка наличия кнопок перехода к предыдущему/следующему месяцу
        date_picker.check_prev_month_button_visibility()
        date_picker.check_next_month_button_visibility()

        current_month_year = date_picker.get_month_year()
        start_month, start_year, tmp = current_month_year.split(" ")

        # нажатие на кнопки перехода к предыдущему месяцу (стрелочка влево) и проверка значений
        date_picker.click_prev_month_button()
        browser.wait_for_timeout(300)
        current_month_year = date_picker.get_month_year()
        prev_month, prev_year, tmp = current_month_year.split(" ")

        num = months.index(start_month)
        expected_month = months[num-1]
        expected_year = start_year

        if start_month == "январь":
            expected_month = "декабрь"
            expected_year = str(int(start_year) - 1)
        assert prev_month == expected_month, \
            f"Expected value {expected_month} is not equal actual value {prev_month} on date picker body"
        assert prev_year == expected_year, \
            f"Expected value {expected_year} is not equal actual value {prev_year} on date picker body"

        # нажатие на кнопки перехода к следующему месяцу (стрелочка вправо) и проверка возврата к началу
        date_picker.click_next_month_button()
        browser.wait_for_timeout(300)
        current_month_year = date_picker.get_month_year()
        next_month, next_year, tmp = current_month_year.split(" ")

        assert next_month == start_month, \
            f"Expected value {start_month} is not equal actual value {next_month} on date picker body"
        assert next_year == start_year, \
            f"Expected value {start_year} is not equal actual value {next_year} on date picker body"

        # нажатие на кнопки перехода к следующему месяцу (стрелочка вправо) и проверка значений
        date_picker.click_next_month_button()
        browser.wait_for_timeout(300)
        current_month_year = date_picker.get_month_year()
        next_month, next_year, tmp = current_month_year.split(" ")

        num = months.index(start_month)
        expected_month = months[num+1]
        expected_year = start_year

        if start_month == "декабрь":
            expected_month = "январь"
            expected_year = str(int(start_year) + 1)

        assert next_month == expected_month, \
            f"Expected value {expected_month} is not equal actual value {next_month} on date picker body"
        assert next_year == expected_year, \
            f"Expected value {expected_year} is not equal actual value {next_year} on date picker body"

        # нажатие на кнопки перехода к предыдущему месяцу (стрелочка влево) и проверка возврата к началу
        date_picker.click_prev_month_button()
        browser.wait_for_timeout(300)
        current_month_year = date_picker.get_month_year()
        prev_month, prev_year, tmp = current_month_year.split(" ")

        assert prev_month == start_month, \
            f"Expected value {start_month} is not equal actual value {prev_month} on date picker body"
        assert prev_year == start_year, \
            f"Expected value {start_year} is not equal actual value {prev_year} on date picker body"

    # @pytest.mark.develop
    def test_day_selection_positive(self, browser: Page) -> None:
        """Проверяет возможность задания корректного значения дня месяца.

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

        months = ["январь", "февраль", "март", "апрель", "май", "июнь",
                  "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"]

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()
        current_month_year = date_picker.get_month_year()
        current_month, current_year, tmp = current_month_year.split(" ")

        # выбираем 15 число текущего года и месяца, проверяем результат
        date_picker.select_day("15")
        browser.wait_for_timeout(300)

        month_num = months.index(current_month) + 1
        expected_date = f"15.{month_num}.{current_year}"
        actual_date = date_input.get_date_field_value()
        assert expected_date == actual_date, \
            f"Expected date {expected_date} is not equal actual date {actual_date}"

    # @pytest.mark.develop
    def test_day_selection_negative(self, browser: Page) -> None:
        """Проверяет возможность задания некорректного значения дня месяца.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()

        # выбор некорректных значений
        incorrect_values = ["0", "32", "ff"]
        for value in incorrect_values:
            try:
                date_picker.select_day(value)
            except AssertionError as e:
                actual_err = f"{e}"
                expected_err =f"Day number {value} is missing on date picker days table"
                assert expected_err == actual_err, \
                    f"Expected error message: '{expected_err}' is nor equal actual error message: '{actual_err}'"

    # @pytest.mark.develop
    def test_year_and_month_selection_positive(self, browser: Page) -> None:
        """Проверяет возможность задания корректных значений года и месяца.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()

        # выбираем 15 января 2024, проверяем результат
        date_picker.select_year_and_month("2024", "01")
        browser.wait_for_timeout(300)
        date_picker.select_day("15")
        browser.wait_for_timeout(300)

        expected_date = "15.01.2024"
        actual_date = date_input.get_date_field_value()
        assert expected_date == actual_date, \
            f"Expected date {expected_date} is not equal actual date {actual_date}"

    # @pytest.mark.develop
    def test_year_and_month_selection_negative(self, browser: Page) -> None:
        """Проверяет возможность задания некорректных значений года и месяца.

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

        lp = LoginPage(browser)
        lp.do_login()

        mp = MainPage(browser)
        mp.should_be_event_panel()

        system_log_events_container = mp.click_events_panel_system_log_tab()
        sidebar_filter = system_log_events_container.click_filter_button()
        browser.wait_for_timeout(500)

        date_input = sidebar_filter.get_start_time_filter()
        date_input.check_switch_mode_button_visibility()
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)
        date_input.click_switch_mode_button()
        browser.wait_for_timeout(500)

        date_picker = date_input.get_date_picker()

        # выбор некорректных значений
        incorrect_years = ["0", "2222", "1212"]
        for value in incorrect_years:
            try:
                date_picker.select_year_and_month(value, "01")
            except AssertionError as e:
                actual_err = f"{e}"
                expected_err =f"Incorrect year value {value} for selection"
                assert expected_err == actual_err, \
                    f"Expected error message: '{expected_err}' is nor equal actual error message: '{actual_err}'"

        incorrect_months = ["june", "aaaa", "0", "14"]
        for value in incorrect_months:
            try:
                date_picker.select_year_and_month("2012", value)
            except AssertionError as e:
                actual_err = f"{e}"
                expected_err =f"Incorrect month value {value} for selection"
                assert expected_err == actual_err, \
                    f"Expected error message: '{expected_err}' is nor equal actual error message: '{actual_err}'"
