"""Модуль для работы с JSON-контейнерами на веб-страницах.

Содержит компонент для чтения и проверки JSON-данных в контейнерах.
Использует playwright для взаимодействия с элементами страницы.
"""

import json
import jsondiff
from playwright.sync_api import Page
from tools.logger import get_logger
from components.base_component import BaseComponent

logger = get_logger("JSON_CONTAINER")


class JsonContainerComponent(BaseComponent):
    """Компонент для работы с JSON-данными на странице.




    Предоставляет методы чтения и проверки JSON-данных в контейнерах.

    """

    def __init__(self, page: Page):
        """Инициализирует JSON-контейнер.

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

        super().__init__(page)

    # Действия:
    def read_data(self, locator):
        """Читает и форматирует JSON-данные из указанного локатора.

        Args:
            locator: Локатор элемента с JSON-данными.

        Returns:
            dict: Распарсенный JSON-объект.

        Raises:
            json.JSONDecodeError: Если данные не могут быть преобразованы в JSON.
        """

        def format_json_string(json_string):
            """Форматирует строку JSON для корректного парсинга.

            Args:
                json_string: Сырая строка с JSON-данными.

            Returns:
                str: Отформатированная строка JSON.
            """

            substrings = json_string.splitlines()
            formatted_string_list = []
            last_substring = substrings.pop()

            for substring in substrings:
                if substring.find(':') == -1:
                    if substring == '{':
                        formatted_string_list.append(substring)
                    elif substring == '}':
                        s1 = formatted_string_list.pop()
                        formatted_string_list.append(s1.rstrip(','))
                        formatted_string_list.append(substring + ',')
                    else:
                        formatted_string_list.append(substring + ',')
                    continue

                key, value = substring.split(':')
                s = ':'.join(['"' + key + '" ', " " + value])

                if value == '{':
                    formatted_string_list.append(s)
                else:
                    formatted_string_list.append(s + ',')

            s2 = formatted_string_list.pop()
            formatted_string_list.append(s2.rstrip(','))
            formatted_string_list.append(last_substring)

            return " ".join(formatted_string_list)

        # Чтение JSON-содержимого из рабочей области
        loc = self.get_locator(locator)
        json_string = loc.inner_text()
        formatted_json_string = format_json_string(json_string)
        return json.loads(formatted_json_string)

    # Проверки:
    def check_json_equals(self, actual, expected, msg):
        """Сравнивает JSON-объекты на идентичность.

        Args:
            actual: Фактический JSON-объект.
            expected: Ожидаемый JSON-объект.
            msg: Сообщение об ошибке.

        Raises:
            AssertionError: Если объекты не идентичны.
        """

        diff = jsondiff.diff(expected, actual, syntax='symmetric')
        assert len(diff) == 0, f"{msg}. DIFF is {diff}"
