"""
Classroom API - Database Persistence Service

Handles hybrid storage: In-Memory + PostgreSQL for sessions.
"""

import logging
from typing import Dict, Optional

from fastapi import HTTPException

from classroom_engine import LessonSession, LessonPhase

logger = logging.getLogger(__name__)

# Database imports (Feature f22)
try:
    from classroom_engine.database import get_db, init_db, SessionLocal
    from classroom_engine.repository import SessionRepository
    DB_ENABLED = True
except ImportError:
    DB_ENABLED = False
    SessionLocal = None
    logger.warning("Classroom DB not available, using in-memory storage only")


# === Hybrid Storage: In-Memory + DB (Feature f22) ===
# In-Memory fuer schnellen Zugriff, DB fuer Persistenz

sessions: Dict[str, LessonSession] = {}
_db_initialized = False


def init_db_if_needed():
    """Initialisiert DB und laedt aktive Sessions beim ersten Aufruf."""
    global _db_initialized
    if _db_initialized or not DB_ENABLED:
        return

    try:
        init_db()
        load_active_sessions_from_db()
        _db_initialized = True
        logger.info("Classroom DB initialized, loaded active sessions")
    except Exception as e:
        logger.error(f"Failed to initialize Classroom DB: {e}")


def load_active_sessions_from_db():
    """Laedt alle aktiven Sessions aus der DB in den Memory-Cache."""
    if not DB_ENABLED:
        return

    try:
        db = SessionLocal()
        repo = SessionRepository(db)

        # Lade alle nicht-beendeten Sessions
        from classroom_engine.db_models import LessonSessionDB, LessonPhaseEnum
        active_db_sessions = db.query(LessonSessionDB).filter(
            LessonSessionDB.current_phase != LessonPhaseEnum.ENDED
        ).all()

        for db_session in active_db_sessions:
            session = repo.to_dataclass(db_session)
            sessions[session.session_id] = session
            logger.info(f"Loaded session {session.session_id} from DB")

        db.close()
    except Exception as e:
        logger.error(f"Failed to load sessions from DB: {e}")


def persist_session(session: LessonSession):
    """Speichert/aktualisiert Session in der DB."""
    if not DB_ENABLED:
        return

    try:
        db = SessionLocal()
        repo = SessionRepository(db)

        existing = repo.get_by_id(session.session_id)
        if existing:
            repo.update(session)
        else:
            repo.create(session)

        db.close()
    except Exception as e:
        logger.error(f"Failed to persist session {session.session_id}: {e}")


def get_session_or_404(session_id: str) -> LessonSession:
    """Holt eine Session oder wirft 404. Prueft auch DB bei Cache-Miss."""
    init_db_if_needed()

    session = sessions.get(session_id)
    if session:
        return session

    # Feature f22: Bei Cache-Miss aus DB laden
    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = SessionRepository(db)
            db_session = repo.get_by_id(session_id)
            if db_session:
                session = repo.to_dataclass(db_session)
                sessions[session.session_id] = session  # In Cache laden
                db.close()
                return session
            db.close()
        except Exception as e:
            logger.error(f"Failed to load session {session_id} from DB: {e}")

    raise HTTPException(status_code=404, detail="Session nicht gefunden")


def delete_session_from_db(session_id: str):
    """Loescht Session aus der DB."""
    if not DB_ENABLED:
        return

    try:
        db = SessionLocal()
        repo = SessionRepository(db)
        repo.delete(session_id)
        db.close()
    except Exception as e:
        logger.error(f"Failed to delete session {session_id} from DB: {e}")
