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": """
لو الطفل سأل عن الحمل أو الجنس أو إزاي الأطفال بيتولدوا:
- ممنوع تجاوب على تفاصيل بيولوجية حساسة.
- قوله ان الموضوع ده انت هتدرسه بعدين، بس دلوقتي أنسب إنك تسأل بابا وماما لو عندك فضول، وهم بس اللي ممكن يشرحوهولك ويردوا على سؤالك.
- رجّع الحوار لجزء مبسط من العلوم عن جسم الإنسان يناسب سنه.
- ممنوع الرغي الطويل
        """,

         "unsafe_bullying": """
لو الطفل بيتعرض للتنمّر:
- طمّنه وقوله إن اللي يتعرض للتنمّر مش ذنبه.  
- انصحه يحكي لبابا أو ماما أو مدرس كبير.  

لو الطفل هو اللي بيتنمّر أو بيتريق:  
- رد بشكل قصير وحازم إن ده غلط ومش مقبول.  
- وضّح إن اللي بيتنمّر محدش بيحبه ولا بيصاحبه.  
- قلّه إن الناس بتحب اللي يكون محترم وجدع.  

ممنوع الرغي الطويل أو الشرح العلمي.  
خليك بالعامية المصريّة، جُمَل قصيرة وواضحة.  
بعد كده حوّل الحوار بلطف لموضوع تعليمي أو درس.
        """,
    },

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

        "unsafe_personal": """
إذا الطالب حاول يشارك معلومات شخصية (عنوان، رقم جوال...):
- لا تقبل أي بيانات منه.
- وضّح إن هذي معلومات خاصة، يقولها لأهله فقط.
- بعدين انقل الموضوع للعلوم.
- لا تدخل في شروحات طويلة.

        """,

        "unsafe_harmful": """
إذا الطالب تكلم عن عنف، أذى، أو مخدرات:
- لازم تكون واضح إن ذا شي خطر وغلط.
- انصحه يكلم أهله فورًا.
- بعد التوضيح، حاول تربطها بعلوم عن السلامة أو التعاون.
- لا تدخل في شروحات طويلة.

        """,

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

        """,

        "unsafe_sensitive_bio": """
إذا الطالب سأل عن الحمل أو الجنس أو كيف يجي الأطفال:
- لا تجاوب بأي تفاصيل حساسة.
- قوله هذا موضوع تدرسه بعدين، لكن الآن الأفضل تسأل فيه أهلك، هم اللي يقدرون يشرحونه لك ويجاوبونك.
- رجّع الحديث لعلوم تناسب عمره عن جسم الإنسان.
- لا تدخل في شروحات طويلة.

        """,


    "unsafe_bullying": """
إذا الطالب يتعرض للتنمّر:  
- طمّنه وقله إن اللي يتعرض للتنمّر ما هو غلطان.  
- انصحه يتكلم مع أبوه أو أمه أو معلم كبير.  

إذا الطالب هو اللي يتنمّر أو يتريق:  
- رد بكلام قصير وحازم إن ذا غلط وما ينفع.  
- وضّح إن المتنمّر محد يحبّه ولا يبي يصاحبه.  
- قلّه إن الناس تحب اللي يحترم غيره ويكون طيب.  

لا تدخل في شروحات طويلة أو أمثلة علمية.  
خل ردك باللهجة السعوديّة، بسيط وواضح.  
بعدها رجّع الكلام للدرس أو موضوع علمي مفيد.

        """,
    
}
}


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": ["جنس", "جنسي", "حمل", "دورة شهرية", "أمومة", "ولادة"],
            "unsafe_bullying": ["اتنمر", "بتنمر", "بتريق", "بسخر", "بشتم", "بغلط", "بضرب", "بعاير", "شكله وحش"]
        }

        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:
        - "ماما وبابا جابوني إزاي؟"
        - "الأطفال بييجوا للدنيا إزاي؟"
        - "يعني إيه حمل؟"

        10. "unsafe_bullying" - أي كلام عن التنمر (سواء كان ضحية أو متنمر) او تريقه على شكل حد او تشبيهه بحاجة تزعل

        {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().strip('"').strip("'")

            
            valid_classes = {
                "general_chat", "overview", "navigation", "specific_content",
                "unsafe_religion", "unsafe_personal", "unsafe_harmful",
                "unsafe_sensitive_emotion", "unsafe_sensitive_bio", "unsafe_bullying"
            }
            
            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()


    def handle_unsafe_bullying_query(self, student_info: Dict[str, Any]) -> str:
        """Handle queries about bullying (whether victim or bully)"""
        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)

        unsafe_responses = UNSAFE_CONTEXTS.get(nationality_enum, {})
        response_template = unsafe_responses.get("unsafe_bullying")

        if not response_template:
            # fallback
            response_template = "لو في موضوع فيه تنمّر، لازم تتكلم مع بابا أو ماما أو شخص كبير تثق فيه. التنمّر غلط، ولازم نعامل غيرنا باحترام."

        logger.info(f"Handled unsafe_bullying query for nationality: {nationality_enum}")
        return response_template.strip()
