# ==============================================
# Breakpilot Drive - Learning State DB Methods
# ==============================================
# Methods for reading/writing student learning state.

import logging
from typing import Optional

from .database_models import StudentLearningState

logger = logging.getLogger(__name__)


class LearningStateMixin:
    """Mixin providing learning state database methods for GameDatabase."""

    async def get_learning_state(self, student_id: str) -> Optional[StudentLearningState]:
        """Get learning state for a student."""
        await self._ensure_connected()
        if not self._pool:
            return None

        try:
            async with self._pool.acquire() as conn:
                row = await conn.fetchrow(
                    """
                    SELECT id, student_id, overall_level, math_level, german_level,
                           english_level, total_play_time_minutes, total_sessions,
                           questions_answered, questions_correct, created_at, updated_at
                    FROM student_learning_state
                    WHERE student_id = $1
                    """,
                    student_id
                )

                if row:
                    return StudentLearningState(
                        id=str(row["id"]),
                        student_id=str(row["student_id"]),
                        overall_level=row["overall_level"],
                        math_level=float(row["math_level"]),
                        german_level=float(row["german_level"]),
                        english_level=float(row["english_level"]),
                        total_play_time_minutes=row["total_play_time_minutes"],
                        total_sessions=row["total_sessions"],
                        questions_answered=row["questions_answered"] or 0,
                        questions_correct=row["questions_correct"] or 0,
                        created_at=row["created_at"],
                        updated_at=row["updated_at"],
                    )
        except Exception as e:
            logger.error(f"Failed to get learning state: {e}")

        return None

    async def create_or_update_learning_state(
        self,
        student_id: str,
        overall_level: int = 3,
        math_level: float = 3.0,
        german_level: float = 3.0,
        english_level: float = 3.0,
    ) -> Optional[StudentLearningState]:
        """Create or update learning state for a student."""
        await self._ensure_connected()
        if not self._pool:
            return None

        try:
            async with self._pool.acquire() as conn:
                row = await conn.fetchrow(
                    """
                    INSERT INTO student_learning_state (
                        student_id, overall_level, math_level, german_level, english_level
                    ) VALUES ($1, $2, $3, $4, $5)
                    ON CONFLICT (student_id) DO UPDATE SET
                        overall_level = EXCLUDED.overall_level,
                        math_level = EXCLUDED.math_level,
                        german_level = EXCLUDED.german_level,
                        english_level = EXCLUDED.english_level,
                        updated_at = NOW()
                    RETURNING id, student_id, overall_level, math_level, german_level,
                              english_level, total_play_time_minutes, total_sessions,
                              questions_answered, questions_correct, created_at, updated_at
                    """,
                    student_id, overall_level, math_level, german_level, english_level
                )

                if row:
                    return StudentLearningState(
                        id=str(row["id"]),
                        student_id=str(row["student_id"]),
                        overall_level=row["overall_level"],
                        math_level=float(row["math_level"]),
                        german_level=float(row["german_level"]),
                        english_level=float(row["english_level"]),
                        total_play_time_minutes=row["total_play_time_minutes"],
                        total_sessions=row["total_sessions"],
                        questions_answered=row["questions_answered"] or 0,
                        questions_correct=row["questions_correct"] or 0,
                        created_at=row["created_at"],
                        updated_at=row["updated_at"],
                    )
        except Exception as e:
            logger.error(f"Failed to create/update learning state: {e}")

        return None

    async def update_learning_stats(
        self,
        student_id: str,
        duration_minutes: int,
        questions_answered: int,
        questions_correct: int,
        new_level: Optional[int] = None,
    ) -> bool:
        """Update learning stats after a game session."""
        await self._ensure_connected()
        if not self._pool:
            return False

        try:
            async with self._pool.acquire() as conn:
                if new_level is not None:
                    await conn.execute(
                        """
                        UPDATE student_learning_state SET
                            total_play_time_minutes = total_play_time_minutes + $2,
                            total_sessions = total_sessions + 1,
                            questions_answered = COALESCE(questions_answered, 0) + $3,
                            questions_correct = COALESCE(questions_correct, 0) + $4,
                            overall_level = $5,
                            updated_at = NOW()
                        WHERE student_id = $1
                        """,
                        student_id, duration_minutes, questions_answered,
                        questions_correct, new_level
                    )
                else:
                    await conn.execute(
                        """
                        UPDATE student_learning_state SET
                            total_play_time_minutes = total_play_time_minutes + $2,
                            total_sessions = total_sessions + 1,
                            questions_answered = COALESCE(questions_answered, 0) + $3,
                            questions_correct = COALESCE(questions_correct, 0) + $4,
                            updated_at = NOW()
                        WHERE student_id = $1
                        """,
                        student_id, duration_minutes, questions_answered, questions_correct
                    )
                return True
        except Exception as e:
            logger.error(f"Failed to update learning stats: {e}")

        return False
