"""
Утилиты для NMP Plus HTTP API
"""

from typing import List, Dict, Any
import time
import re

def fix_windows_encoding(text: str) -> str:
    """Исправляет кракозябры от Windows-клиентов"""
    if not isinstance(text, str):
        text = str(text)
    
    try:
        # Пробуем разные варианты декодирования
        
        # Вариант 1: cp1251 -> utf-8 (основная проблема Windows)
        try:
            if any(ord(char) > 127 for char in text):
                # Пробуем исправить двойное кодирование
                fixed = text.encode('latin1').decode('utf-8')
                return fixed
        except:
            pass
        
        # Вариант 2: Исправляем конкретные кракозябры
        replacements = {
            'РџР\xa0РћР•РљРў': 'ПРОЕКТ',
            'РњРћР"Р•Р\xa0РќР': 'МОДЕРН',
            'РђР\xa0РҐР': 'АРХИ',
            'РџР\xa0РћР': 'ПРО',
            'Р\xa0РЈРЎРЎРљРђРЇ': 'РУССКАЯ',
            'Р›РћРљРђР›Р': 'ЛОКАЛ',
            'Р—РђР¦Р': 'ЗАЦ',
            'РўР•РҐРќР': 'ТЕХНИ',
            'Р§Р•РЎРљР': 'ЧЕСК',
            'Р"Р•РўРђР›Р': 'ДЕТАЛ',
        }
        
        for bad, good in replacements.items():
            text = text.replace(bad, good)
        
        return text
        
    except Exception as e:
        print(f"⚠️ Ошибка исправления кодировки: {e}")
        return text

def clean_unicode_surrogates(text: str) -> str:
    """УСИЛЕННАЯ очистка суррогатных символов Unicode, которые вызывают ошибки кодировки"""
    if not isinstance(text, str):
        text = str(text)
    
    # СНАЧАЛА исправляем кракозябры
    text = fix_windows_encoding(text)
    
    # МНОГОУРОВНЕВАЯ очистка суррогатных символов
    try:
        # Метод 1: Пробуем разные стратегии кодирования
        try:
            # Сначала пробуем surrogatepass
            cleaned = text.encode('utf-8', errors='surrogatepass').decode('utf-8', errors='ignore')
        except:
            try:
                # Потом surrogateescape
                cleaned = text.encode('utf-8', errors='surrogateescape').decode('utf-8', errors='ignore')
            except:
                # Наконец ignore
                cleaned = text.encode('utf-8', errors='ignore').decode('utf-8', errors='ignore')
        
        # Метод 2: Удаляем все суррогатные символы (расширенный диапазон)
        cleaned = re.sub(r'[\uD800-\uDFFF]', '', cleaned)
        
        # Метод 3: Удаляем другие проблемные Unicode символы
        cleaned = re.sub(r'[\uFFFE\uFFFF]', '', cleaned)
        
        # Метод 4: Финальная проверка кодирования
        try:
            cleaned.encode('utf-8')
        except UnicodeEncodeError:
            # Если все еще проблемы, оставляем только безопасные символы
            cleaned = ''.join(char for char in cleaned if ord(char) < 128)
        
        return cleaned
    except Exception as e:
        # Аварийная очистка
        try:
            return ''.join(char for char in str(text) if ord(char) < 128)
        except:
            return f"[UNICODE_ERROR: {str(e)}]"

def clean_data_for_response(data: Any) -> Any:
    """Рекурсивная очистка данных от суррогатных символов для безопасной JSON сериализации"""
    if isinstance(data, str):
        return clean_unicode_surrogates(data)
    elif isinstance(data, dict):
        return {str(k): clean_data_for_response(v) for k, v in data.items()}
    elif isinstance(data, list):
        return [clean_data_for_response(item) for item in data]
    elif isinstance(data, tuple):
        return tuple(clean_data_for_response(item) for item in data)
    else:
        # Для других типов данных (int, float, bool, None) возвращаем как есть
        return data

def clean_search_results(results: List[Dict]) -> List[Dict]:
    """Очистка результатов поиска для JSON сериализации"""
    clean_results = []
    for result in results:
        clean_result = {}
        for key, value in result.items():
            if key == "embedding":
                continue  # Пропускаем векторы
            elif key == "timestamp" and hasattr(value, 'isoformat'):
                clean_result[key] = value.isoformat()
            elif isinstance(value, (dict, list)):
                clean_result[key] = clean_data_for_response(value)
            else:
                clean_result[key] = clean_unicode_surrogates(str(value)) if value is not None else None
        clean_results.append(clean_result)
    return clean_results

def validate_chat_quality(conversation: str) -> Dict[str, Any]:
    """Валидация качества чата перед сохранением"""
    
    # Базовые проверки
    if len(conversation) < 50:
        return {
            "valid": False,
            "reason": "Диалог слишком короткий",
            "score": 0.1
        }
    
    # Проверка на наличие диалога
    if "Пользователь:" not in conversation and "Ассистент:" not in conversation:
        return {
            "valid": False,
            "reason": "Не найдена структура диалога",
            "score": 0.2
        }
    
    # Подсчет качественных метрик
    lines = conversation.split('\n')
    user_lines = [l for l in lines if l.startswith("Пользователь:")]
    assistant_lines = [l for l in lines if l.startswith("Ассистент:")]
    
    # Базовая оценка качества
    quality_score = 0.5
    
    # Бонус за сбалансированность диалога
    if len(user_lines) > 0 and len(assistant_lines) > 0:
        balance = min(len(user_lines), len(assistant_lines)) / max(len(user_lines), len(assistant_lines))
        quality_score += balance * 0.3
    
    # Бонус за длину ответов
    avg_length = sum(len(line) for line in lines) / len(lines) if lines else 0
    if avg_length > 50:
        quality_score += 0.2
    
    # Проверка на технические термины (программирование)
    tech_terms = ['код', 'функция', 'API', 'база данных', 'алгоритм', 'ошибка', 'debug']
    tech_count = sum(1 for term in tech_terms if term.lower() in conversation.lower())
    if tech_count > 2:
        quality_score += 0.1
    
    return {
        "valid": quality_score > 0.4,
        "score": min(quality_score, 1.0),
        "metrics": {
            "total_lines": len(lines),
            "user_messages": len(user_lines),
            "assistant_messages": len(assistant_lines),
            "avg_line_length": avg_length,
            "tech_terms_found": tech_count
        }
    }

def generate_success_response(data: Any, message: str = "Операция выполнена успешно") -> Dict[str, Any]:
    """Генерация стандартного успешного ответа с очисткой от суррогатных символов"""
    # Очищаем все данные от суррогатных символов
    clean_data = clean_data_for_response(data)
    clean_message = clean_unicode_surrogates(message)
    
    return {
        "success": True,
        "message": clean_message,
        "data": clean_data,
        "timestamp": time.time()
    }

def generate_error_response(error: str, details: Any = None) -> Dict[str, Any]:
    """Генерация стандартного ответа об ошибке с очисткой от суррогатных символов"""
    clean_error = clean_unicode_surrogates(error)
    clean_details = clean_data_for_response(details) if details else None
    
    response = {
        "success": False,
        "error": clean_error,
        "timestamp": time.time()
    }
    if clean_details:
        response["details"] = clean_details
    return response 