import os
import psycopg2
from psycopg2.extras import RealDictCursor
from typing import List, Dict, Optional, Tuple
import logging
from services.connection_pool import ConnectionPool
from enum import Enum
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from core import StudyLanguage
from schemas import StudentProfile
logger = logging.getLogger(__name__)



class ChatDatabaseService:
    """Service for managing chat history using a shared, robust connection pool"""

    def __init__(self, pool_handler: 'ConnectionPool'):
        self.pool_handler = pool_handler

    def get_student_nationality(self, student_id: str) -> Optional[str]:
        """Get student nationality from database"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor(cursor_factory=RealDictCursor) as cur:
                cur.execute(
                    "SELECT nationality FROM students WHERE student_id = %s",
                    (student_id,)
                )
                result = cur.fetchone()
                return result["nationality"] if result else None

    def get_student_info(self, student_id: str) -> Optional[StudentProfile]:
        """Get complete student information with explicit language awareness"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor(cursor_factory=RealDictCursor) as cur:
                cur.execute(
                    """
                    SELECT student_id, student_name, grade, language, nationality 
                    FROM students 
                    WHERE student_id = %s
                    """,
                    (student_id,)
                )
                result = cur.fetchone()
                if result:
                    study_language = StudyLanguage.ARABIC if result['language'] else StudyLanguage.ENGLISH
                    
                    return StudentProfile(
                        student_id=result['student_id'],
                        student_name=result['student_name'],
                        grade=result['grade'],
                        study_language=study_language,
                        nationality=result['nationality'],
                        is_arabic=result['language']
                    )
                return None

    def get_student_grade_and_language(self, student_id: str) -> Optional[Tuple[int, bool, StudyLanguage]]:
        """Get student grade, language preference, and explicit study language"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor(cursor_factory=RealDictCursor) as cur:
                cur.execute(
                    "SELECT grade, language FROM students WHERE student_id = %s",
                    (student_id,)
                )
                result = cur.fetchone()
                if result:
                    study_language = StudyLanguage.ARABIC if result['language'] else StudyLanguage.ENGLISH
                    return (result["grade"], result["language"], study_language)
                return None

    def get_chat_history(self, student_id: str, limit: int = 20) -> List[Dict[str, str]]:
        """Get chat history for a student, returns in chronological order"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor(cursor_factory=RealDictCursor) as cur:
                cur.execute(
                    """
                    SELECT role, content
                    FROM chat_history
                    WHERE student_id = %s
                    ORDER BY created_at DESC
                    LIMIT %s;
                    """,
                    (student_id, limit)
                )
                results = cur.fetchall()
                return [{"role": row["role"], "content": row["content"]} for row in reversed(results)]

    def add_message(self, student_id: str, role: str, content: str):
        """Add a message to chat history"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor() as cur:
                cur.execute(
                    """
                    INSERT INTO chat_history (student_id, role, content)
                    VALUES (%s, %s, %s);
                    """,
                    (student_id, role, content)
                )
                conn.commit()

    def clear_history(self, student_id: str):
        """Clear chat history for a student"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor() as cur:
                cur.execute(
                    "DELETE FROM chat_history WHERE student_id = %s",
                    (student_id,)
                )
                conn.commit()

    def limit_history(self, student_id: str, max_messages: int = 40):
        """Keep only recent messages for a student"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor() as cur:
                cur.execute(
                    """
                    DELETE FROM chat_history 
                    WHERE student_id = %s 
                    AND role != 'system'
                    AND id NOT IN (
                        SELECT id FROM chat_history 
                        WHERE student_id = %s AND role != 'system'
                        ORDER BY created_at DESC 
                        LIMIT %s
                    );
                    """,
                    (student_id, student_id, max_messages)
                )
                conn.commit()

    def update_student_info(self, student_id: str, grade: Optional[int] = None, 
                           language: Optional[bool] = None, nationality: Optional[str] = None):
        """Update student information"""
        updates = []
        params = []
        
        if grade is not None:
            updates.append("grade = %s")
            params.append(grade)
        
        if language is not None:
            updates.append("language = %s")
            params.append(language)
            
        if nationality is not None:
            updates.append("nationality = %s")
            params.append(nationality)
        
        if updates:
            params.append(student_id)
            with self.pool_handler.get_connection() as conn:
                with conn.cursor() as cur:
                    cur.execute(
                        f"""
                        UPDATE students 
                        SET {', '.join(updates)}
                        WHERE student_id = %s
                        """,
                        params
                    )
                    conn.commit()
                    
                    # Log the language update explicitly
                    if language is not None:
                        study_language = StudyLanguage.ARABIC if language else StudyLanguage.ENGLISH
                        logger.info(f"Updated student {student_id} language to {study_language.value}")

    def create_student(self, student_id: str, student_name: str, grade: int, 
                      language: bool, nationality: str = 'EGYPTIAN'):
        """Create a new student record"""
        with self.pool_handler.get_connection() as conn:
            with conn.cursor() as cur:
                cur.execute(
                    """
                    INSERT INTO students (student_id, student_name, grade, language, nationality)
                    VALUES (%s, %s, %s, %s, %s)
                    ON CONFLICT (student_id) DO NOTHING;
                    """,
                    (student_id, student_name, grade, language, nationality)
                )
                conn.commit()
                
                # Log the explicit language information
                study_language = StudyLanguage.ARABIC if language else StudyLanguage.ENGLISH
                logger.info(f"Created student {student_id} ({student_name}) - Grade: {grade}, Language: {study_language.value}, Nationality: {nationality}")

    def get_student_language_summary(self, student_id: str) -> Optional[Dict[str, str]]:
        """Get a human-readable summary of student's language settings"""
        student_info = self.get_student_info(student_id)
        if not student_info:
            return None
            
        is_egyptian = False
        if hasattr(student_info.nationality, 'value'):
             # If it's the Enum object
             is_egyptian = student_info.nationality.value.lower() == "egyptian"
        else:
             # If strictly string fallback
             is_egyptian = str(student_info.nationality).lower() == "egyptian"

        nationality_desc = "مصري" if is_egyptian else "سعودي"
        language_desc = "بالعربي" if student_info.study_language == StudyLanguage.ARABIC else "بالإنجليزي"
        
        return {
            "student_id": student_id,
            "student_name": student_info.student_name,
            "study_language": student_info.study_language.value,
            "nationality": str(student_info.nationality.value if hasattr(student_info.nationality, 'value') else student_info.nationality),
            "grade": str(student_info.grade),
            "description": f"طالب {nationality_desc} في الصف {student_info.grade} يدرس {language_desc}"
        }

    def get_students_by_language(self, study_language: StudyLanguage) -> List[Dict]:
        """Get all students who study in a specific language"""
        language_bool = True if study_language == StudyLanguage.ARABIC else False
        
        with self.pool_handler.get_connection() as conn:
            with conn.cursor(cursor_factory=RealDictCursor) as cur:
                cur.execute(
                    """
                    SELECT student_id, student_name, grade, nationality
                    FROM students 
                    WHERE language = %s
                    ORDER BY grade, student_name
                    """,
                    (language_bool,)
                )
                results = cur.fetchall()
                return [
                    {
                        'student_id': row['student_id'],
                        'student_name': row['student_name'],
                        'grade': row['grade'],
                        'nationality': row['nationality'],
                        'study_language': study_language.value
                    }
                    for row in results
                ]
            
            