import os
import requests
import json
import time
import logging
from typing import Optional, Dict, Any

# Импортируем наши модули
try:
    from .privacy_engine import PrivacyEngine
    from .knowledge_base import KnowledgeBase
except ImportError:
    # Заглушки на случай, когда модули ещё не созданы
    PrivacyEngine = type('PrivacyEngine', (), {})
    KnowledgeBase = type('KnowledgeBase', (), {})

logger = logging.getLogger(__name__)

class AIEngine:
    def __init__(self):
        self.huggingface_token = os.getenv("HUGGINGFACE_TOKEN")
        try:
            self.knowledge_base = KnowledgeBase()
            self.privacy_engine = PrivacyEngine()
        except:
            # Заглушки на случай ошибок инициализации
            self.knowledge_base = None
            self.privacy_engine = None
            
        self.rate_limit_delay = 1
        self.available_models = [
            "google/flan-t5-large",      # Основная модель
            "microsoft/DialoGPT-medium", # Запасная модель
            "facebook/blenderbot-400M-distill",
            "gpt2",
        ]
        self.current_model = self.available_models[0]
        
    def is_huggingface_available(self):
        """Проверка доступности Hugging Face"""
        return bool(self.huggingface_token)
    
    def test_connection(self) -> Dict[str, Any]:
        """Тестирование подключения к Hugging Face"""
        if not self.huggingface_token:
            return {
                "status": "error",
                "message": "HUGGINGFACE_TOKEN не установлен"
            }
        
        try:
            headers = {"Authorization": f"Bearer {self.huggingface_token}"}
            response = requests.get(
                "https://huggingface.co/api/whoami-v2",
                headers=headers,
                timeout=10
            )
            
            if response.status_code == 200:
                user_info = response.json()
                return {
                    "status": "success",
                    "message": "Hugging Face доступен",
                    "user": user_info.get('name', 'Unknown'),
                    "can_load_models": user_info.get('canLoadModels', False)
                }
            else:
                return {
                    "status": "error",
                    "message": f"Ошибка авторизации: {response.status_code}"
                }
                
        except Exception as e:
            return {
                "status": "error",
                "message": f"Ошибка подключения: {str(e)}"
            }
    
    def process_query(self, user_query: str, context: Optional[Dict] = None) -> str:
        """Трехфазная обработка запроса с приватностью и самообучением"""
        
        logger.info(f"🔍 Обработка запроса: {user_query}")
        
        # Если Hugging Face не настроен, используем fallback
        if not self.is_huggingface_available():
            return "❌ Hugging Face не настроен. Установите HUGGINGFACE_TOKEN."
        
        try:
            # Фаза 0: Очистка приватности
            if self.privacy_engine:
                cleaned_query, privacy_context = self.privacy_engine.clean_query(user_query, context)
                logger.info(f"🛡️ Очищенный запрос: {cleaned_query}")
            else:
                cleaned_query = user_query
                privacy_context = {}
        except:
            cleaned_query = user_query
            privacy_context = {}
        
        # Фаза 1: Локальная база знаний
        try:
            if self.knowledge_base:
                local_response = self.knowledge_base.find_similar(cleaned_query)
                if local_response and local_response != "❌ Не знаю":
                    logger.info("✅ Ответ найден в локальной базе знаний")
                    # Восстанавливаем контекст для персонализации ответа
                    if self.privacy_engine:
                        personalized_response = self.privacy_engine.restore_context(local_response, privacy_context)
                    else:
                        personalized_response = local_response
                    return personalized_response
        except Exception as e:
            logger.error(f"Ошибка поиска в локальной базе: {e}")
        
        # Фаза 2: Hugging Face API
        logger.info("🔄 Запрос к Hugging Face API")
        hf_response = self._call_hugging_face(cleaned_query, context)
        
        # Фаза 3: Восстановление контекста и сохранение в базу знаний
        if "❌" not in hf_response and "⏳" not in hf_response:
            try:
                if self.privacy_engine:
                    personalized_response = self.privacy_engine.restore_context(hf_response, privacy_context)
                else:
                    personalized_response = hf_response
                
                # Сохраняем ОЧИЩЕННУЮ версию для самообучения
                if self.knowledge_base:
                    self.knowledge_base.save_qa(
                        cleaned_query, 
                        hf_response,
                        original_question=user_query
                    )
                    logger.info("💾 Очищенный ответ сохранён в локальную базу знаний")
                
                return personalized_response
            except Exception as e:
                logger.error(f"Ошибка сохранения в базу знаний: {e}")
                return hf_response
        else:
            return hf_response
    
    def _call_hugging_face(self, query: str, context: Optional[Dict] = None) -> str:
        """Запрос к Hugging Face Inference API"""
        
        if not self.huggingface_token:
            return "❌ Hugging Face недоступен: HUGGINGFACE_TOKEN не установлен"
        
        try:
            headers = {
                "Authorization": f"Bearer {self.huggingface_token}",
                "Content-Type": "application/json"
            }
            
            # Формируем промпт для лучшего ответа
            prompt = self._build_prompt(query, context)
            
            payload = {
                "inputs": prompt,
                "parameters": {
                    "max_new_tokens": 500,
                    "temperature": 0.7,
                    "do_sample": True,
                    "return_full_text": False,
                },
                "options": {
                    "wait_for_model": True,
                    "use_cache": True
                }
            }
            
            # Задержка для соблюдения лимитов
            time.sleep(self.rate_limit_delay)
            
            logger.info(f"🤖 Отправка запроса к модели: {self.current_model}")
            
            response = requests.post(
                f"https://api-inference.huggingface.co/models/{self.current_model}",
                headers=headers,
                json=payload,
                timeout=30
            )
            
            if response.status_code == 200:
                result = response.json()
                answer = self._extract_answer(result)
                
                if answer:
                    logger.info("✅ Успешный ответ от Hugging Face")
                    return answer
                else:
                    return "❌ Не удалось получить ответ от модели"
                    
            elif response.status_code == 503:
                # Модель загружается
                loading_time = response.headers.get("X-Wait-For", "20")
                return f"⏳ Модель загружается, попробуйте через {loading_time} секунд"
                
            elif response.status_code == 429:
                # Слишком много запросов
                return "❌ Слишком много запросов. Подождите немного."
                
            elif response.status_code == 401:
                return "❌ Неверный токен Hugging Face. Проверьте HUGGINGFACE_TOKEN."
                
            else:
                error_msg = f"❌ Ошибка Hugging Face API: {response.status_code}"
                try:
                    error_detail = response.json()
                    if 'error' in error_detail:
                        error_msg += f" - {error_detail['error']}"
                except:
                    pass
                return error_msg
                
        except requests.exceptions.Timeout:
            return "❌ Таймаут подключения к Hugging Face"
        except requests.exceptions.ConnectionError:
            return "❌ Ошибка подключения к Hugging Face. Проверьте интернет."
        except Exception as e:
            logger.error(f"Неожиданная ошибка: {str(e)}")
            return f"❌ Неожиданная ошибка: {str(e)}"
    
    def _build_prompt(self, query: str, context: Optional[Dict] = None) -> str:
        """Строим промпт для лучшего ответа"""
        
        system_prompt = """Ты - помощник Jarvis AI. Отвечай кратко, понятно и по делу. 
Будь полезным и давай практические советы."""

        if context and context.get('problem_type') == 'technical':
            system_prompt += " Ты помогаешь решить технические проблемы."
        elif context and context.get('problem_type') == 'file_management':
            system_prompt += " Ты помогаешь с управлением файлами и папками."
        
        prompt = f"{system_prompt}\n\nПользователь: {query}\n\nПомощник:"
        
        return prompt
    
    def _extract_answer(self, hf_response: Any) -> str:
        """Извлекаем ответ из разных форматов Hugging Face API"""
        
        try:
            if isinstance(hf_response, list) and len(hf_response) > 0:
                # Стандартный формат для текстовых моделей
                first_item = hf_response[0]
                if 'generated_text' in first_item:
                    text = first_item['generated_text'].strip()
                    # Убираем повторения промпта если есть
                    if 'Помощник:' in text:
                        text = text.split('Помощник:')[-1].strip()
                    return text
                elif 'text' in first_item:
                    return first_item['text'].strip()
            
            elif isinstance(hf_response, dict):
                # Альтернативный формат
                if 'generated_text' in hf_response:
                    return hf_response['generated_text'].strip()
                elif 'text' in hf_response:
                    return hf_response['text'].strip()
            
            # Если формат неизвестен, пытаемся извлечь текст
            response_str = str(hf_response)
            if len(response_str) < 1000:  # Не возвращаем слишком длинные сырые данные
                return response_str
            
            return "❌ Не удалось обработать ответ от модели"
            
        except Exception as e:
            logger.error(f"Ошибка извлечения ответа: {e}")
            return "❌ Ошибка обработка ответа от модели"
    
    def switch_model(self, model_name: str) -> bool:
        """Переключение на другую модель Hugging Face"""
        if model_name in self.available_models:
            self.current_model = model_name
            logger.info(f"🔄 Переключено на модель: {model_name}")
            return True
        else:
            logger.warning(f"Модель {model_name} не найдена в доступных")
            return False


# Создаем глобальный экземпляр для использования в других модулях
ai_engine = AIEngine()