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
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}"

رد باللهجة السعوديّة الطبيعية، خلّ الرد بسيط وودود.  

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





UNSAFE_CONTEXTS: Dict[StudentNationality, Dict[str, str]] = {
    StudentNationality.EGYPTIAN: {
        "unsafe_religion": """
الموضوع ده مش مناسب نتكلم فيه هنا. أي حاجة دينيّة الأحسن تسأل فيها بابا أو ماما أو حد كبير بتثق فيه.  
تعالى نرجع للدرس—تحب نكمل في الموضوع اللي بنتعلمه سوا؟
        """,

        "unsafe_personal": """
مينفعش تقول أسرارك أو تفاصيلك الشخصية هنا، دي حاجات تحتفظ بيها لنفسك أو تقولها لحد كبير زي بابا أو ماما.  
طب إيه رأيك نكمّل في الدرس ونشوف النقطة اللي كنا شغالين عليها؟
        """,

        "unsafe_harmful": """
الكلام ده خطر ومش مناسب. لو حسيت بحاجة زي دي، لازم تكلم بابا أو ماما أو حد كبير تثق فيه.  
تحب نغيّر الموضوع ونرجع للدرس بتاعنا؟
        """,

        "unsafe_sensitive_emotion": """
أنا حاسس إنك زعلان، وده طبيعي. الأحسن تحكي لماما أو بابا أو حد كبير قريب منك.  
تحب نرجع للدرس ونشغل نفسنا باللي كنا بنتعلمه؟
        """,

        "unsafe_sensitive_bio": """
الموضوع ده انت هتدرسه بعدين، بس دلوقتي أنسب إنك تسأل بابا وماما لو عندك فضول، وهم بس اللي ممكن يشرحوهولك ويردوا على سؤالك.  
تحب نكمّل سوا في الدرس اللي فاتحينه دلوقتي؟
        """,
    },

    StudentNationality.SAUDI: {
        "unsafe_religion": """
هذا موضوع ما نقدر نتكلم فيه هنا. أي شي يخص الدين الأفضل تسأل فيه أبوك أو أمك أو شخص كبير تثق فيه.  
خلنا نرجع للدرس—تحب نكمل في الموضوع اللي ندرسه الحين؟
        """,

        "unsafe_personal": """
ما ينفع تشارك أسرارك أو معلوماتك الشخصية هنا، هذي لازم تقولها بس لأهلك أو شخص كبير تثق فيه.  
وش رايك نرجع للدرس ونكمل اللي كنا نشتغل عليه؟
        """,

        "unsafe_harmful": """
الكلام ذا خطر وما يصلح. إذا حسيت بشي زي كذا لازم تحكي مع أبوك أو أمك أو شخص كبير تثق فيه.  
خلنا نغيّر الموضوع ونرجع للدرس؟
        """,

        "unsafe_sensitive_emotion": """
واضح إنك حزين، وهذا شعور طبيعي. الأفضل تحكي مع أهلك أو شخص كبير قريب منك.  
تحب نرجع للدرس ونركز فيه؟
        """,

        "unsafe_sensitive_bio": """
هذا موضوع تدرسه بعدين، لكن الآن الأفضل تسأل فيه أهلك، هم اللي يقدرون يشرحونه لك ويجاوبونك.  
تحب نرجع للدرس اللي احنا فيه؟
        """,
    }
}

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 using LLM with conversation context"""
        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)

        # Get recent conversation context
        conversation_context = self.get_recent_conversation_context(student_id, max_messages=5)

        # Keywords grouped by category for hint detection
        unsafe_keywords = {
            "unsafe_religion": ["دين", "ديانة", "دينى", "دينك", "الله", "إله", "عبادة", "صلوات", "قرآن", "إنجيل", "تورا"],
            "unsafe_personal": ["عنوان", "ساكن", "موبايل", "رقم", "تليفون", "شارع", "عمارة", "شقة"],
            "unsafe_harmful": ["مخدرات", "سجاير", "انتحار", "اضرب", "أقتل", "أذى", "دم", "خطر"],
            "unsafe_sensitive_emotion": ["زعلان", "حزين", "موت", "اتوفى", "وَفاة", "بعيط", "عايط", "اكتئاب"],
            "unsafe_sensitive_bio": ["جنس", "جنسي", "حمل", "دورة شهرية", "أمومة", "ولادة"]
        }

        q_lower = query.lower()
        keyword_flags = [cat for cat, kws in unsafe_keywords.items() if any(kw in q_lower for kw in kws)]

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

        1. "general_chat" - أسئلة دردشة عامة وشخصية عن الطالب أو المدرس
        2. "overview" - أسئلة عن نظرة عامة على المنهج أو المحتوى الكامل
        3. "navigation" - أسئلة عن وحدة أو مفهوم معين
        4. "specific_content" - أسئلة محددة عن موضوع علمي معين
        5. "unsafe_religion" - أي كلام عن الدين أو اختراع ديانة أو عبادة
        6. "unsafe_personal" - مشاركة أسرار أو تفاصيل شخصية حساسة
        7. "unsafe_harmful" - كلام عن العنف، الأذى للنفس، المخدرات، الشتائم
        8. "unsafe_sensitive_emotion" - مواقف حزينة جداً مثل فقدان شخص أو بكاء شديد
        9. "unsafe_sensitive_bio" - أي أسئلة عن الإنجاب، الحمل، أو كيف الأطفال بييجوا للدنيا

        أمثلة على unsafe_sensitive_bio:
        - "ماما وبابا جابوني إزاي؟"
        - "الأطفال بييجوا للدنيا إزاي؟"
        - "يعني إيه حمل؟"

        {conversation_context}

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

        if keyword_flags:
            classification_prompt += f"\n ملاحظة: السؤال يحتوي على كلمات قد تكون مرتبطة بالفئات: {', '.join(keyword_flags)}. \
    تأكد من السياق جيداً قبل التصنيف."

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

        try:
            response = self.openai_service.client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[{"role": "user", "content": classification_prompt}],
                temperature=0,
                max_tokens=20
            )
            classification: str = response.choices[0].message.content.strip().lower()
            
            valid_classes = {
                "general_chat", "overview", "navigation", "specific_content",
                "unsafe_religion", "unsafe_personal", "unsafe_harmful",
                "unsafe_sensitive_emotion", "unsafe_sensitive_bio"
            }
            
            if classification in valid_classes:
                logger.info(f"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})")
                print(f"Query classified as: {classification} for query: '{query}' (with context, flags={keyword_flags})")
                return classification
            else:
                logger.warning(
                    f"Unexpected classification '{classification}' for query '{query}', "
                    "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_unsafe_religion_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries about religion or religious topics"""
        nationality_str: str = student_info.get('nationality', 'egyptian')
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get the appropriate unsafe response template
        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_religion")
        
        if not response_template:
            # Fallback to Egyptian template if not found
            unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
            response_template = unsafe_responses.get("unsafe_religion", 
                "هذا الموضوع غير مناسب للمناقشة هنا. يرجى التحدث مع الوالدين أو شخص بالغ موثوق.")
        
        logger.info(f"Handled unsafe_religion query for nationality: {nationality_enum}")
        return response_template.strip()

    def handle_unsafe_personal_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries involving sharing personal secrets or sensitive information"""
        nationality_str: str = student_info.get('nationality', 'egyptian')
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get the appropriate unsafe response template
        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_personal")
        
        if not response_template:
            # Fallback to Egyptian template if not found
            unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
            response_template = unsafe_responses.get("unsafe_personal", 
                "لا يجب مشاركة المعلومات الشخصية هنا. تحدث مع الوالدين فقط حول هذه الأمور.")
        
        logger.info(f"Handled unsafe_personal query for nationality: {nationality_enum}")
        return response_template.strip()

    def handle_unsafe_harmful_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries about violence, self-harm, drugs, or inappropriate language"""
        nationality_str: str = student_info.get('nationality', 'egyptian')
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get the appropriate unsafe response template
        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_harmful")
        
        if not response_template:
            # Fallback to Egyptian template if not found
            unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
            response_template = unsafe_responses.get("unsafe_harmful", 
                "هذا الموضوع غير آمن وغير مناسب. يرجى التحدث مع شخص بالغ موثوق إذا كان لديك مشاعر صعبة.")
        
        logger.warning(f"Handled unsafe_harmful query for nationality: {nationality_enum}")
        return response_template.strip()

    def handle_unsafe_sensitive_emotion_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries involving very sad situations like loss or extreme sadness"""
        nationality_str: str = student_info.get('nationality', 'egyptian')
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get the appropriate unsafe response template
        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_sensitive_emotion")
        
        if not response_template:
            # Fallback to Egyptian template if not found
            unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
            response_template = unsafe_responses.get("unsafe_sensitive_emotion", 
                "أشعر أنك حزين. هذه مشاعر طبيعية، ولكن من المهم التحدث مع الوالدين أو شخص بالغ موثوق.")
        
        logger.info(f"Handled unsafe_sensitive_emotion query for nationality: {nationality_enum}")
        return response_template.strip()

    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_unsafe_sensitive_bio_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries about sensitive biology topics"""
        nationality_str: str = student_info.get('nationality', 'egyptian')
        nationality_mapping = {
            'egyptian': StudentNationality.EGYPTIAN,
            'saudi': StudentNationality.SAUDI
        }
        nationality_enum = nationality_mapping.get(nationality_str.lower().strip(), StudentNationality.EGYPTIAN)
        
        # Get the appropriate unsafe response template
        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_sensitive_bio")
        
        if not response_template:
            # Fallback to Egyptian template if not found
            unsafe_responses = UNSAFE_CONTEXTS.get(StudentNationality.EGYPTIAN, {})
            response_template = unsafe_responses.get("unsafe_sensitive_bio", 
                "الموضوع ده مش مناسب هنا. الأحسن تسأل فيه بابا أو ماما.")
        
        logger.info(f"Handled unsafe_sensitive_bio query for nationality: {nationality_enum}")
        return response_template.strip()