"""
Teacher Feedback Repository.

CRUD-Operationen fuer Lehrer-Feedback (Phase 7).
Ermoeglicht Lehrern, Bugs, Feature-Requests und Verbesserungen zu melden.
"""
from datetime import datetime
from typing import Optional, List, Dict, Any

from sqlalchemy.orm import Session as DBSession

from .db_models import (
    TeacherFeedbackDB, FeedbackTypeEnum, FeedbackStatusEnum,
    FeedbackPriorityEnum,
)


class TeacherFeedbackRepository:
    """
    Repository fuer Lehrer-Feedback CRUD-Operationen.

    Ermoeglicht Lehrern, Feedback (Bugs, Feature-Requests, Verbesserungen)
    direkt aus dem Lehrer-Frontend zu senden.
    """

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

    def create(
        self,
        teacher_id: str,
        title: str,
        description: str,
        feedback_type: str = "improvement",
        priority: str = "medium",
        teacher_name: str = "",
        teacher_email: str = "",
        context_url: str = "",
        context_phase: str = "",
        context_session_id: str = None,
        user_agent: str = "",
        related_feature: str = None,
    ) -> TeacherFeedbackDB:
        """Erstellt neues Feedback."""
        import uuid

        db_feedback = TeacherFeedbackDB(
            id=str(uuid.uuid4()),
            teacher_id=teacher_id,
            teacher_name=teacher_name,
            teacher_email=teacher_email,
            title=title,
            description=description,
            feedback_type=FeedbackTypeEnum(feedback_type),
            priority=FeedbackPriorityEnum(priority),
            status=FeedbackStatusEnum.NEW,
            related_feature=related_feature,
            context_url=context_url,
            context_phase=context_phase,
            context_session_id=context_session_id,
            user_agent=user_agent,
        )

        self.db.add(db_feedback)
        self.db.commit()
        self.db.refresh(db_feedback)
        return db_feedback

    def get_by_id(self, feedback_id: str) -> Optional[TeacherFeedbackDB]:
        """Holt Feedback nach ID."""
        return self.db.query(TeacherFeedbackDB).filter(
            TeacherFeedbackDB.id == feedback_id
        ).first()

    def get_all(
        self,
        status: str = None,
        feedback_type: str = None,
        limit: int = 100,
        offset: int = 0
    ) -> List[TeacherFeedbackDB]:
        """Holt alle Feedbacks mit optionalen Filtern."""
        query = self.db.query(TeacherFeedbackDB)

        if status:
            query = query.filter(TeacherFeedbackDB.status == FeedbackStatusEnum(status))
        if feedback_type:
            query = query.filter(TeacherFeedbackDB.feedback_type == FeedbackTypeEnum(feedback_type))

        return query.order_by(
            TeacherFeedbackDB.created_at.desc()
        ).offset(offset).limit(limit).all()

    def get_by_teacher(self, teacher_id: str, limit: int = 50) -> List[TeacherFeedbackDB]:
        """Holt Feedback eines bestimmten Lehrers."""
        return self.db.query(TeacherFeedbackDB).filter(
            TeacherFeedbackDB.teacher_id == teacher_id
        ).order_by(
            TeacherFeedbackDB.created_at.desc()
        ).limit(limit).all()

    def update_status(
        self,
        feedback_id: str,
        status: str,
        response: str = None,
        responded_by: str = None
    ) -> Optional[TeacherFeedbackDB]:
        """Aktualisiert den Status eines Feedbacks."""
        db_feedback = self.get_by_id(feedback_id)
        if not db_feedback:
            return None

        db_feedback.status = FeedbackStatusEnum(status)
        if response:
            db_feedback.response = response
            db_feedback.responded_at = datetime.utcnow()
            db_feedback.responded_by = responded_by

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

    def delete(self, feedback_id: str) -> bool:
        """Loescht ein Feedback."""
        db_feedback = self.get_by_id(feedback_id)
        if not db_feedback:
            return False

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

    def get_stats(self) -> Dict[str, Any]:
        """Gibt Statistiken ueber alle Feedbacks zurueck."""
        all_feedback = self.db.query(TeacherFeedbackDB).all()

        stats = {
            "total": len(all_feedback),
            "by_status": {},
            "by_type": {},
            "by_priority": {},
        }

        for fb in all_feedback:
            # By Status
            status = fb.status.value
            stats["by_status"][status] = stats["by_status"].get(status, 0) + 1

            # By Type
            fb_type = fb.feedback_type.value
            stats["by_type"][fb_type] = stats["by_type"].get(fb_type, 0) + 1

            # By Priority
            priority = fb.priority.value
            stats["by_priority"][priority] = stats["by_priority"].get(priority, 0) + 1

        return stats

    def to_dict(self, db_feedback: TeacherFeedbackDB) -> Dict[str, Any]:
        """Konvertiert DB-Model zu Dictionary."""
        return {
            "id": db_feedback.id,
            "teacher_id": db_feedback.teacher_id,
            "teacher_name": db_feedback.teacher_name,
            "teacher_email": db_feedback.teacher_email,
            "title": db_feedback.title,
            "description": db_feedback.description,
            "feedback_type": db_feedback.feedback_type.value,
            "priority": db_feedback.priority.value,
            "status": db_feedback.status.value,
            "related_feature": db_feedback.related_feature,
            "context_url": db_feedback.context_url,
            "context_phase": db_feedback.context_phase,
            "context_session_id": db_feedback.context_session_id,
            "user_agent": db_feedback.user_agent,
            "response": db_feedback.response,
            "responded_at": db_feedback.responded_at.isoformat() if db_feedback.responded_at else None,
            "responded_by": db_feedback.responded_by,
            "created_at": db_feedback.created_at.isoformat() if db_feedback.created_at else None,
            "updated_at": db_feedback.updated_at.isoformat() if db_feedback.updated_at else None,
        }
