import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))

from typing import Dict, Any
from core import StudentNationality, StudyLanguage, Models
import logging

logger = logging.getLogger(__name__)


GENERAL_CHAT_CONTEXTS: Dict[StudentNationality, str] = {
    StudentNationality.EGYPTIAN: """
مَعلومات الطِّفل:
- الاِسم: {student_name} (هو هنا بالانجليزي بس انت اكتبه بالعربي دايما )
- السَّنة: {grade} (قولها سنة رابعه او خامسة )
- الجِنسيّة: مَصري
- لُغة الدِّراسة: {study_lang}

السُّؤال: "{query}"

خَليك بتِرُد بالعاميّة المَصري، وبطريقة بسيطة وودودة.  

- لو الطِّفل سأل: "إنت مين؟" → رد بالهوية المخصصة ليك (أنا عَنان...).
- لو الطِّفل سأل: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب اللي فوق (الاسم + الصف)، مثلاً:
  "أيوه طبعًا، إنت/أنتِ (اسم الطالب بالعربي) في سنة (سنة الطالب بالعربي). عايز نكمّل النهارده في موضوع معين في العلوم؟"
- لو السُّؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه.
- لو الطفل سلم عليك او رحب بيك باي طريقة او اي لغة قوله اهلا بيك/بيكي يا (اسم الطالب بالعربي) انا هنا عشان أَساعدك/أَساعدِك في العلوم
- لو السُّؤال دردشة عامة أو خارج المنهج والعلوم وملوش علاقة بهوية الطالب أو هويتك → متردش على الكلام نهائيًا، وقوله الرد دا:
  "الوقت دا للمذاكرة في العلوم، أنا هنا عشان أَساعدك/أَساعدِك في العلوم وبس." 
  وبعدها اسأله بطريقة ودودة لو يحب يختار موضوع في العلوم تتكلموا فيه.
    """,

    StudentNationality.SAUDI: """
معلومات الطالب:
- الاسم: {student_name}
- الصف: {grade}
- الجنسية: سعودي
- لغة الدراسة: {study_lang}

السؤال: "{query}"

- لو الطِّفل سأل: "إنت مين؟" → رد بالهوية المخصصة ليك (أنا عَنان...).
- لو الطِّفل سأل: "أنا مين؟" أو "إنت عارف أنا مين؟" → رد باستخدام بيانات الطالب اللي فوق (الاسم + الصف)، مثلاً:
  "أيوه طبعًا، إنت/أنتِ (اسم الطالب بالعربي) في سنة (سنة الطالب بالعربي). عايز نكمّل النهارده في موضوع معين في العلوم؟"
- لو السُّؤال له علاقة بالعلوم أو بالمنهج → جاوب عليه.
- لو الطفل سلم عليك او رحب بيك باي طريقة او اي لغة قوله اهلا بيك/بيكي يا (اسم الطالب بالعربي) انا هنا عشان أَساعدك/أَساعدِك في العلوم
- لو السُّؤال دردشة عامة أو خارج المنهج والعلوم وملوش علاقة بهوية الطالب أو هويتك → متردش على الكلام نهائيًا، وقوله الرد دا:
  "الوقت دا للمذاكرة في العلوم، أنا هنا عشان أَساعدك/أَساعدِك في العلوم وبس." 
  وبعدها اسأله بطريقة ودودة لو يحب يختار موضوع في العلوم تتكلموا فيه.
    """
}





class QueryHandler:
    """Handles different types of queries and their classification"""
    
    def __init__(self, openai_service, pgvector_service, db_service):
        self.openai_service = openai_service
        self.pgvector = pgvector_service
        self.db_service = db_service

    def get_recent_conversation_context(self, student_id: str, max_messages: int = 5) -> str:
        """Get recent conversation history for context"""
        try:
            # Get conversation history from database
            full_history = self.db_service.get_chat_history(student_id)
            
            # Get last max_messages messages (excluding system messages)
            recent_messages = []
            for msg in reversed(full_history):
                if msg['role'] != 'system' and len(recent_messages) < max_messages:
                    recent_messages.insert(0, msg)  # Insert at beginning to maintain order
                elif len(recent_messages) >= max_messages:
                    break
            
            if not recent_messages:
                return "لا توجد رسائل سابقة في المحادثة."
            
            # Format the context
            context_parts = ["المحادثة الأخيرة:"]
            for msg in recent_messages:
                role_label = "الطالب" if msg['role'] == 'user' else "المعلم"
                context_parts.append(f"{role_label}: {msg['content'][:200]}...")  # Limit message length
                
            return "\n".join(context_parts)
            
        except Exception as e:
            logger.warning(f"Error getting conversation context for {student_id}: {e}")
            return "لا يمكن الحصول على سياق المحادثة."


    def classify_query_type(self, query: str, student_info: Dict[str, Any], student_id: str) -> str:
        """
        Enhanced query classification. It first checks for a specific, rule-based
        pattern for 'game_help' and then falls back to the LLM for other cases.
        """
        
        q_lower = query.lower()
        if "game context:" in q_lower and "user query:" in q_lower:
            logger.info("Query classified as 'game_help' by rule-based check.")
            print("Query classified as 'game_help' by rule-based check.")
            return "game_help"


        if not self.openai_service.is_available():
            return "specific_content"
            
        is_arabic: bool = student_info.get('is_arabic', True)
        grade: int = student_info.get('grade', 4)

        conversation_context = self.get_recent_conversation_context(student_id, max_messages=5)

        classification_prompt = f"""
        صنف السؤال التالي إلى إحدى الفئات التالية، مع مراعاة سياق المحادثة الأخيرة:

        1. "general_chat" -  أسئلة دردشة عامة وشخصية عن الطالب أو المدرس او اي سؤال عن اي شئ غير مرتبط بالعلوم عموما او المنهج او الدراسة
        2. "overview" - أسئلة عن نظرة عامة على المنهج أو المحتوى الكامل
        3. "navigation" - أسئلة عن وحدة أو مفهوم معين
        4. "specific_content" - أسئلة محددة عن موضوع علمي معين
        
        {conversation_context}

        السؤال الحالي: "{query}"
        الطالب يدرس باللغة: {"العربية" if is_arabic else "الإنجليزية"}
        الصف: {grade}
        
        تعليمات مهمة:
        - استخدم سياق المحادثة الأخيرة لفهم السؤال بشكل أفضل
        - إذا كان الطالب يتحدث عن موضوع علمي معين وسأل سؤال متعلق به، فهو "specific_content"
        - إذا كان السؤال غامض، اعتمد على السياق لتحديد القصد الحقيقي
        - مثال: إذا كان يتحدث عن النباتات وسأل "كيف تأكل؟" فهو يقصد تغذية النباتات وليس الطعام العادي
        """

        classification_prompt += "\n\nرد فقط بكلمة واحدة من الفئات المحددة أعلاه"

        try:
            response = self.openai_service.client.chat.completions.create(
                model=Models.classification,
                messages=[{"role": "user", "content": classification_prompt}],
                temperature=0,
                max_tokens=20
            )
            classification: str = response.choices[0].message.content.strip().lower().strip('"').strip("'")
            
            valid_classes = {
                "general_chat", "overview", "navigation", "specific_content"
            }
            
            if classification in valid_classes:
                logger.info(f"Query classified as: {classification} by LLM for query: '{query}'")
                print(f"Query classified as: {classification} by LLM for query: '{query}'")
                return classification
            else:
                logger.warning(
                    f"Unexpected LLM classification '{classification}' for query '{query}', "
                    "defaulting to 'specific_content'"
                )
                return "specific_content"
                
        except Exception as e:
            logger.warning(f"Error in LLM query classification: {e}, defaulting to 'specific_content'")
            return "specific_content"


                
        except Exception as e:
            logger.warning(f"Error in query classification: {e}, defaulting to 'specific_content'")
            return "specific_content"

    def handle_general_chat_query(self, query: str, student_info: Dict[str, Any]) -> str:
        """Handle general chat queries using only student information"""
        student_name: str = student_info.get('student_name', 'الطالب')
        grade: int = student_info.get('grade', 4)
        nationality_str: str = student_info.get('nationality', 'egyptian')
        is_arabic: bool = student_info.get('is_arabic', True)

        study_lang = "العربية" if is_arabic else "الإنجليزية"

        # Map nationality string to enum
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get template with fallback
        template = GENERAL_CHAT_CONTEXTS.get(nationality_enum)
        if not template:
            logger.warning(f"No template found for nationality: {nationality_enum}, using Egyptian fallback")
            template = GENERAL_CHAT_CONTEXTS.get(StudentNationality.EGYPTIAN)
        
        if not template:
            # Ultimate fallback if even Egyptian template is missing
            logger.error("No templates available in GENERAL_CHAT_CONTEXTS")
            template = """
معلومات الطالب:
- الاسم: {student_name}
- الصف: {grade}
- الجنسية: {nationality}
- لغة الدراسة: {study_lang}

السؤال: "{query}"

رد بطريقة بسيطة وودودة باستخدام معلومات الطالب المتوفرة أعلاه.
            """
        
        try:
            context = template.format(
                student_name=student_name,
                grade=grade,
                nationality=nationality_str,
                study_lang=study_lang,
                query=query
            )
            return context
        except Exception as e:
            logger.error(f"Error formatting template: {e}")
            # Return a simple fallback context
            return f"""
معلومات الطالب: {student_name}, الصف {grade}
السؤال: "{query}"
رد بطريقة ودودة وبسيطة.
            """


    def handle_overview_query(self, student_info: Dict[str, Any], subject: str = "Science") -> str:
        """Handle curriculum overview queries using JSON-based data"""
        if not self.pgvector:
            if student_info['study_language'] == StudyLanguage.ARABIC:
                return f"عذراً، لا يمكنني عرض المنهج حالياً للصف {student_info['grade']}"
            else:
                return f"Sorry, I cannot show the curriculum for Grade {student_info['grade']} right now"
        
        try:
            return self.pgvector.get_overview_response(
                student_info['grade'], 
                student_info['is_arabic'], 
                subject
            )
        except Exception as e:
            logger.error(f"Error getting overview response: {e}")
            if student_info['study_language'] == StudyLanguage.ARABIC:
                return f"عذراً، حدث خطأ في عرض المنهج للصف {student_info['grade']}"
            else:
                return f"Sorry, there was an error showing the curriculum for Grade {student_info['grade']}"

    def handle_navigation_query(self, query: str, student_info: Dict[str, Any], subject: str = "Science") -> str:
        """Handle unit/concept navigation queries using JSON structure"""
        if not self.pgvector:
            return self.handle_overview_query(student_info, subject)
        
        try:
            return self.pgvector.get_unit_navigation_response(
                query, 
                student_info['grade'], 
                student_info['is_arabic'], 
                subject
            )
        except Exception as e:
            logger.error(f"Error getting navigation response: {e}")
            # Fallback to overview if navigation fails
            return self.handle_overview_query(student_info, subject)


    def handle_game_help_query(self, message: str):
        """
        Extracts 'game_context' and 'user_query' from the full message text.
        Expected format:
            game context: <context text>
            user query: <query text>
        Returns a dictionary with both parts.
        """

        game_context = ""
        user_query = ""

        parts = message.split("user query:")
        if len(parts) == 2:
            game_context = parts[0].replace("game context:", "").strip()
            user_query = parts[1].strip()

        return game_context, user_query
