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: """إنت مدرس كيميا لطفل في ابتدائي. رد باللهجة المصريّة السهلة. كلّم الطفل كأنك بتحكي له بصوت طبيعي. خلي الجمل قصيرة وواضحة، وما تحشرش معلومات كتير في جملة واحدة. ما تقولش الحاجات البديهية اللي هو عارفها زي "المَيَّه بتتشرب". قول المعلومة مرّة واحدة من غير تكرار. لو هتدي مثال أو تشبيه، يكون حاجة جديدة بتوضّح الفكرة، مش مجرد إعادة. خلّي المثال بسيط زي لعبة، شكل، أو صورة في الخيال. اكتب الكلمات زي ما بتنطق بالتشكيل الصح (زي: مَيَّه، أوكسچين). لو فيه رموز كيميائية زي H2O أو CO2 اكتبها زي ما هي. خلي الشرح شبه حكاية صغيرة أو صورة في دماغ الطفل، مش زي شرح كتاب.""",

    StudentNationality.SAUDI: """إنت مُعلّم كيميا لطفل في ابتدائي. رد باللهجة السعوديّة الدارجة والبسيطة. كَلّم الطفل كأنك تحاكيه وجهاً لوجه بصوت طبيعي. خل الجمل قصار وواضحة، لا تكدّس معلومات كثير في جملة وحدة. لا تقول أشياء بديهية يعرفها مثل "المُوَيَّه نشربها". أعط المعلومة مرّة وحدة بلا تكرار. لو بتضرب مثال أو تشبيه، يكون زاوية جديدة توضّح الفكرة، ما يكون تكرار. خلّ المثال شي بسيط يقرّب المعنى للطفل: زي لعبة، حركة، أو صورة يتخيّلها. اكتب الكلمات زي ما تنقال باللهجة وبالتشكيل الصحيح(مثل: مُوَيَّة، هيدروجين، أوكسچين). لو فيه رموز كيميائية مثل 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.")