"""Утилиты для обработки текста и JSON."""

import json
import re
from typing import Any, Dict, List, Match, Set

from nltk.tokenize import word_tokenize


def lemmatize_token(token: str, analyzer: Any) -> str:
    """Лемматизирует отдельный токен текста."""
    try:
        return analyzer.parse(token)[0].normal_form
    except Exception:
        return token


def lemmatize_text_russian(text: str, morph: Any) -> str:
    """Лемматизирует текст на русском языке."""
    text = re.sub(r'[^\w\s]', '', text)
    tokens = word_tokenize(text, language='russian')

    lemmatized_tokens = [lemmatize_token(word, morph) for word in tokens]
    return ' '.join(lemmatized_tokens)


def process_json_list(json_list: List[Any]) -> List[Any]:
    """Обрабатывает список JSON данных."""
    result_list = []
    for element in json_list:
        if isinstance(element, dict):
            # Для объекта в списке берем только ключи
            values_list = list(element.keys())
            result_list.append(values_list)
        else:
            # Если элемент списка не объект, оставляем как есть
            result_list.append(element)
    return result_list


def process_json_dict(json_dict: Dict[str, Any]) -> List[Any]:
    """Обрабатывает словарь JSON данных."""
    return list(json_dict.values())


def parse_and_process_json(json_str: str) -> str:
    """Парсит JSON и преобразует его структуру."""
    parsed_content = json.loads(json_str)

    if isinstance(parsed_content, list):
        processed_content = process_json_list(parsed_content)
    elif isinstance(parsed_content, dict):
        processed_content = process_json_dict(parsed_content)
    else:
        processed_content = parsed_content

    return json.dumps(processed_content, indent=2, ensure_ascii=False)


def replace_json(match: Match[str]) -> str:
    """Заменяет JSON блок его обработанной версией."""
    try:
        values_json = parse_and_process_json(match.group(1))

        # Сохраняем markdown формат
        return f'```json\n{values_json}\n```'
    except json.JSONDecodeError:
        # Если парсинг JSON не удался, возвращаем исходный текст
        return match.group(0)


def extract_json_values_from_markdown(markdown_text: str) -> str:
    """Заменяет JSON блоки в markdown на их значения без ключей."""
    # Паттерн для поиска JSON блоков в markdown (```json и ```)
    pattern = r'```json\s*([\s\S]*?)\s*```'

    # Заменяем все JSON блоки их значениями
    modified_text = re.sub(pattern, replace_json, markdown_text)

    return modified_text


def prepare_text_for_analysis(text: str) -> str:
    """Подготавливает текст к анализу, удаляя специальные символы."""
    return text.replace('\\', '')


def extract_entities(text: str, stopwords: Set[str]) -> Set[str]:
    """Извлекает технические сущности из текста."""
    technical_pattern = re.compile(r'\b[a-zA-Z][a-zA-Z0-9_]*(?:[/_\-\.:]?[a-zA-Z0-9]+)*\b')

    found_entities = technical_pattern.findall(text)
    normalized_entities = (entity.lower() for entity in found_entities)
    return {entity for entity in normalized_entities if entity not in stopwords}
