import logging
import os
from typing import List, Dict
from fastapi import HTTPException
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from core import StudentNationality, Models
from services.pgvector_service import PGVectorService
from services.openai_service import OpenAIService
from services.chat_database_service import ChatDatabaseService
 

logger = logging.getLogger(__name__)


SYSTEM_PROMPTS: Dict[StudentNationality, str] = {
StudentNationality.EGYPTIAN: """
إنت مُدرّس كيميا لطفل في ابتدائي.  
رد باللهجة المصريّة الطبيعيّة.  
خلي الكلام بسيط وواضح، كفاية يوصّل الفكرة من غير تطويل.  
الجمل تكون قصيرة نسبيًّا، بس مش ناقصة.  
استخدم التشكيل بس على الكلمات اللي ممكن الـTTS ينطقها غلط.  
اشرح المعلومة خطوة خطوة من غير تكرار.  
ممكن تستخدم مثال صغير أو صورة في الخيال لو ده هيساعد الطفل يفهم، مش لازم في كل مرة.  
خليك بتحكي كأنها لقطة من الحياة، مش شرح كتاب.  
الرموز الكيميائية زي H2O أو CO2 تكتب زي ما هي.  
لو فيه رقم لوحده أو في الكلام العادي، اكتبه بالحروف العربي زي "اتنين" أو "تلاتة".  
الهدف: رد قصير ومباشر يعلّم، من غير زيادة كلام ولا سطحية.
"""

,

    StudentNationality.SAUDI: """
إنت معلّم كيميا لطفل في ابتدائي.  
رد باللهجة السعوديّة البسيطة.  
خل الكلام واضح وقصير يكفي يوصّل الفكرة.  
الجمل تكون قصيرة نسبيًّا، لكن لا تكون ناقصة.  
استخدم التشكيل بس على الكلمات اللي ممكن الـTTS يقرأها غلط.  
اشرح المعلومة خطوة خطوة من غير تكرار.  
ممكن تضيف مثال صغير أو صورة تخيّل تساعد الطفل يفهم، بس مو لازم دائم.  
خلي الشرح سواليف كأنها موقف من الحياة، مو كلام رسمي.  
الرموز الكيميائية مثل H2O أو CO2 تكتب زي ما هي.  
لو فيه رقم لوحده أو في النص العادي، اكتبه بالحروف العربي زي "اثنين" أو "ثلاثة".  
الهدف: رد بسيط وذكي يوضّح الفكرة من غير زيادة ولا سطحية.
"""

}


class AgentService:
    """Service class for handling AI agent conversations using database memory"""

    def __init__(self, use_pgvector: bool = False):
        self.openai_service = OpenAIService()
        if not self.openai_service.is_available():
            logger.warning("Warning: OPENAI_API_KEY not found. Agent service will be disabled.")
            self.client = None
        else:
            self.client = self.openai_service.client

        # Use database for conversation memory
        self.db_service = ChatDatabaseService()
        self.pgvector = PGVectorService() if use_pgvector else None

    def is_available(self) -> bool:
        return self.client is not None

    def get_conversation_history(self, student_id: str) -> List[Dict[str, str]]:
        """Get conversation history from database"""
        return self.db_service.get_chat_history(student_id)

    def add_message_to_history(self, student_id: str, message: str, role: str = "user"):
        """Add message to database"""
        self.db_service.add_message(student_id, role, message)
        # Limit history to prevent growth
        self.db_service.limit_history(student_id, max_messages=38)

    def generate_response(
        self,
        user_message: str,
        student_id: str,
        nationality: StudentNationality = StudentNationality.EGYPTIAN,
        model: str = Models.chat,
        temperature: float = 1.0,
        top_k: int = 3
    ) -> str:
        """Generate AI response using database memory"""
        if not self.is_available():
            raise HTTPException(status_code=500, detail="Agent service not available")

        try:
            # Add user message to database
            self.add_message_to_history(student_id, user_message, "user")

            # Get conversation history from database
            conversation_history = self.get_conversation_history(student_id)

            # Pick system prompt
            system_prompt = SYSTEM_PROMPTS.get(nationality, SYSTEM_PROMPTS[StudentNationality.EGYPTIAN])

            # Prepare messages
            messages = []
            
            # Check if system message exists
            has_system_message = conversation_history and conversation_history[0].get("role") == "system"
            
            if not has_system_message:
                messages.append({"role": "system", "content": system_prompt})
                # Add system message to database
                self.add_message_to_history(student_id, system_prompt, "system")
            
            # Add conversation history
            messages.extend(conversation_history)

            # Optional pgvector enrichment
            if self.pgvector:
                try:
                    query_embedding = self.openai_service.generate_embedding(user_message)
                    neighbors = self.pgvector.search_nearest(query_embedding, limit=top_k)

                    if neighbors:
                        context_message = "Knowledge base search results:\n"
                        for n in neighbors:
                            context_message += f"- ID {n['id']} (distance {n['distance']:.4f})\n"
                        messages.append({"role": "system", "content": context_message})
                except Exception as e:
                    logger.warning(f"Error using pgvector: {e}")

            # Generate AI response
            response = self.client.chat.completions.create(
                model=model,
                messages=messages,
                temperature=temperature
            )

            ai_response = response.choices[0].message.content.strip()
            if not ai_response:
                raise ValueError("Empty response from AI model")

            # Add AI response to database
            self.add_message_to_history(student_id, ai_response, "assistant")
            
            return ai_response

        except Exception as e:
            logger.error(f"Error generating AI response: {e}")
            raise HTTPException(status_code=500, detail=f"AI response generation failed: {str(e)}")

    def search_similar(self, query_embedding: List[float], top_k: int = 3):
        """Optional pgvector search"""
        if not self.pgvector:
            raise HTTPException(status_code=400, detail="PGVector service not enabled")
        return self.pgvector.search_nearest(query_embedding, limit=top_k)

    def close(self):
        """Close database connection"""
        if self.db_service:
            self.db_service.close()


# ----------------- Test -----------------
if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    agent = AgentService(use_pgvector=True)

    if agent.is_available():
        try:
            reply = agent.generate_response(
                "هو يعني إيه ذَرّة؟", 
                student_id="student_001",
                nationality=StudentNationality.EGYPTIAN
            )
            print("AI:", reply)
        except Exception as e:
            print(f"Test failed: {e}")
        finally:
            agent.close()
    else:
        print("Agent service not available. Check OPENAI_API_KEY.")