"""
Template Repository.

CRUD-Operationen fuer Stunden-Vorlagen (Feature f37).
"""
from typing import Optional, List

from sqlalchemy.orm import Session as DBSession

from .db_models import LessonTemplateDB
from .models import LessonTemplate, get_default_durations


class TemplateRepository:
    """Repository fuer Stunden-Vorlagen (Feature f37)."""

    def __init__(self, db: DBSession):
        self.db = db

    # ==================== CREATE ====================

    def create(self, template: LessonTemplate) -> LessonTemplateDB:
        """Erstellt eine neue Vorlage."""
        db_template = LessonTemplateDB(
            id=template.template_id,
            teacher_id=template.teacher_id,
            name=template.name,
            description=template.description,
            subject=template.subject,
            grade_level=template.grade_level,
            phase_durations=template.phase_durations,
            default_topic=template.default_topic,
            default_notes=template.default_notes,
            is_public=template.is_public,
            usage_count=template.usage_count,
        )
        self.db.add(db_template)
        self.db.commit()
        self.db.refresh(db_template)
        return db_template

    # ==================== READ ====================

    def get_by_id(self, template_id: str) -> Optional[LessonTemplateDB]:
        """Holt eine Vorlage nach ID."""
        return self.db.query(LessonTemplateDB).filter(
            LessonTemplateDB.id == template_id
        ).first()

    def get_by_teacher(
        self,
        teacher_id: str,
        include_public: bool = True
    ) -> List[LessonTemplateDB]:
        """
        Holt alle Vorlagen eines Lehrers.

        Args:
            teacher_id: ID des Lehrers
            include_public: Auch oeffentliche Vorlagen anderer Lehrer einbeziehen
        """
        if include_public:
            return self.db.query(LessonTemplateDB).filter(
                (LessonTemplateDB.teacher_id == teacher_id) |
                (LessonTemplateDB.is_public == True)
            ).order_by(
                LessonTemplateDB.usage_count.desc()
            ).all()
        else:
            return self.db.query(LessonTemplateDB).filter(
                LessonTemplateDB.teacher_id == teacher_id
            ).order_by(
                LessonTemplateDB.created_at.desc()
            ).all()

    def get_public_templates(self, limit: int = 20) -> List[LessonTemplateDB]:
        """Holt oeffentliche Vorlagen, sortiert nach Beliebtheit."""
        return self.db.query(LessonTemplateDB).filter(
            LessonTemplateDB.is_public == True
        ).order_by(
            LessonTemplateDB.usage_count.desc()
        ).limit(limit).all()

    def get_by_subject(
        self,
        subject: str,
        teacher_id: Optional[str] = None
    ) -> List[LessonTemplateDB]:
        """Holt Vorlagen fuer ein bestimmtes Fach."""
        query = self.db.query(LessonTemplateDB).filter(
            LessonTemplateDB.subject == subject
        )
        if teacher_id:
            query = query.filter(
                (LessonTemplateDB.teacher_id == teacher_id) |
                (LessonTemplateDB.is_public == True)
            )
        else:
            query = query.filter(LessonTemplateDB.is_public == True)

        return query.order_by(
            LessonTemplateDB.usage_count.desc()
        ).all()

    # ==================== UPDATE ====================

    def update(self, template: LessonTemplate) -> Optional[LessonTemplateDB]:
        """Aktualisiert eine Vorlage."""
        db_template = self.get_by_id(template.template_id)
        if not db_template:
            return None

        db_template.name = template.name
        db_template.description = template.description
        db_template.subject = template.subject
        db_template.grade_level = template.grade_level
        db_template.phase_durations = template.phase_durations
        db_template.default_topic = template.default_topic
        db_template.default_notes = template.default_notes
        db_template.is_public = template.is_public

        self.db.commit()
        self.db.refresh(db_template)
        return db_template

    def increment_usage(self, template_id: str) -> Optional[LessonTemplateDB]:
        """Erhoeht den Usage-Counter einer Vorlage."""
        db_template = self.get_by_id(template_id)
        if not db_template:
            return None

        db_template.usage_count += 1
        self.db.commit()
        self.db.refresh(db_template)
        return db_template

    # ==================== DELETE ====================

    def delete(self, template_id: str) -> bool:
        """Loescht eine Vorlage."""
        db_template = self.get_by_id(template_id)
        if not db_template:
            return False

        self.db.delete(db_template)
        self.db.commit()
        return True

    # ==================== CONVERSION ====================

    def to_dataclass(self, db_template: LessonTemplateDB) -> LessonTemplate:
        """Konvertiert DB-Model zu Dataclass."""
        return LessonTemplate(
            template_id=db_template.id,
            teacher_id=db_template.teacher_id,
            name=db_template.name,
            description=db_template.description or "",
            subject=db_template.subject or "",
            grade_level=db_template.grade_level or "",
            phase_durations=db_template.phase_durations or get_default_durations(),
            default_topic=db_template.default_topic or "",
            default_notes=db_template.default_notes or "",
            is_public=db_template.is_public,
            usage_count=db_template.usage_count,
            created_at=db_template.created_at,
            updated_at=db_template.updated_at,
        )
