"""
Analytics-Modul fuer Classroom Engine (Phase 5).

Bietet Statistiken und Auswertungen fuer Unterrichtsstunden:
- Phasen-Dauer Statistiken
- Overtime-Analyse
- Lehrer-Dashboard Daten
- Post-Lesson Reflection

WICHTIG: Keine wertenden Metriken (z.B. "Sie haben 70% geredet").
Fokus auf neutrale, hilfreiche Statistiken.
"""

from datetime import datetime
from typing import Optional, List, Dict, Any

from .analytics_models import (
    PhaseStatistics,
    SessionSummary,
    TeacherAnalytics,
    LessonReflection,
)

# Re-export models for backward compatibility
__all__ = [
    "PhaseStatistics",
    "SessionSummary",
    "TeacherAnalytics",
    "LessonReflection",
    "AnalyticsCalculator",
]


class AnalyticsCalculator:
    """Berechnet Analytics aus Session-Daten."""

    PHASE_DISPLAY_NAMES = {
        "einstieg": "Einstieg",
        "erarbeitung": "Erarbeitung",
        "sicherung": "Sicherung",
        "transfer": "Transfer",
        "reflexion": "Reflexion",
    }

    @classmethod
    def calculate_session_summary(
        cls,
        session_data: Dict[str, Any],
        phase_history: List[Dict[str, Any]]
    ) -> SessionSummary:
        """Berechnet die Zusammenfassung einer Session."""
        session_id = session_data.get("session_id", "")
        teacher_id = session_data.get("teacher_id", "")
        class_id = session_data.get("class_id", "")
        subject = session_data.get("subject", "")
        topic = session_data.get("topic")

        lesson_started = session_data.get("lesson_started_at")
        lesson_ended = session_data.get("lesson_ended_at")

        if isinstance(lesson_started, str):
            lesson_started = datetime.fromisoformat(lesson_started.replace("Z", "+00:00"))
        if isinstance(lesson_ended, str):
            lesson_ended = datetime.fromisoformat(lesson_ended.replace("Z", "+00:00"))

        total_duration = 0
        if lesson_started and lesson_ended:
            total_duration = int((lesson_ended - lesson_started).total_seconds())

        phase_durations = session_data.get("phase_durations", {})
        planned_duration = sum(phase_durations.values()) * 60

        phase_stats = []
        total_overtime = 0
        phases_with_overtime = 0
        total_pause_count = 0
        total_pause_seconds = 0
        phases_completed = 0

        for entry in phase_history:
            phase = entry.get("phase", "")
            if phase in ["not_started", "ended"]:
                continue

            planned_seconds = phase_durations.get(phase, 0) * 60
            actual_seconds = entry.get("duration_seconds", 0) or 0
            difference = actual_seconds - planned_seconds

            had_overtime = difference > 0
            overtime_seconds = max(0, difference)

            if had_overtime:
                total_overtime += overtime_seconds
                phases_with_overtime += 1

            pause_count = entry.get("pause_count", 0) or 0
            pause_seconds = entry.get("total_pause_seconds", 0) or 0
            total_pause_count += pause_count
            total_pause_seconds += pause_seconds

            if entry.get("ended_at"):
                phases_completed += 1

            phase_stats.append(PhaseStatistics(
                phase=phase,
                display_name=cls.PHASE_DISPLAY_NAMES.get(phase, phase),
                planned_duration_seconds=planned_seconds,
                actual_duration_seconds=actual_seconds,
                difference_seconds=difference,
                had_overtime=had_overtime,
                overtime_seconds=overtime_seconds,
                was_extended=entry.get("was_extended", False),
                extension_minutes=entry.get("extension_minutes", 0) or 0,
                pause_count=pause_count,
                total_pause_seconds=pause_seconds,
            ))

        return SessionSummary(
            session_id=session_id, teacher_id=teacher_id,
            class_id=class_id, subject=subject, topic=topic,
            date=lesson_started or datetime.now(),
            total_duration_seconds=total_duration,
            planned_duration_seconds=planned_duration,
            phases_completed=phases_completed, total_phases=5,
            phase_statistics=phase_stats,
            total_overtime_seconds=total_overtime,
            phases_with_overtime=phases_with_overtime,
            total_pause_count=total_pause_count,
            total_pause_seconds=total_pause_seconds,
        )

    @classmethod
    def calculate_teacher_analytics(
        cls,
        sessions: List[Dict[str, Any]],
        period_start: datetime,
        period_end: datetime
    ) -> TeacherAnalytics:
        """Berechnet aggregierte Statistiken fuer einen Lehrer."""
        if not sessions:
            return TeacherAnalytics(teacher_id="", period_start=period_start, period_end=period_end)

        teacher_id = sessions[0].get("teacher_id", "")

        total_sessions = len(sessions)
        completed_sessions = sum(1 for s in sessions if s.get("lesson_ended_at"))

        total_minutes = 0
        for session in sessions:
            started = session.get("lesson_started_at")
            ended = session.get("lesson_ended_at")
            if started and ended:
                if isinstance(started, str):
                    started = datetime.fromisoformat(started.replace("Z", "+00:00"))
                if isinstance(ended, str):
                    ended = datetime.fromisoformat(ended.replace("Z", "+00:00"))
                total_minutes += (ended - started).total_seconds() / 60

        phase_durations_sum: Dict[str, List[int]] = {
            "einstieg": [], "erarbeitung": [], "sicherung": [],
            "transfer": [], "reflexion": [],
        }

        overtime_count = 0
        overtime_seconds_total = 0
        phase_overtime: Dict[str, int] = {}
        pause_counts = []
        pause_durations = []
        subjects: Dict[str, int] = {}
        classes: Dict[str, int] = {}

        for session in sessions:
            subject = session.get("subject", "")
            class_id = session.get("class_id", "")
            subjects[subject] = subjects.get(subject, 0) + 1
            classes[class_id] = classes.get(class_id, 0) + 1

            history = session.get("phase_history", [])
            session_has_overtime = False
            session_pause_count = 0
            session_pause_duration = 0
            phase_durations_dict = session.get("phase_durations", {})

            for entry in history:
                phase = entry.get("phase", "")
                if phase in phase_durations_sum:
                    duration = entry.get("duration_seconds", 0) or 0
                    phase_durations_sum[phase].append(duration)

                    planned = phase_durations_dict.get(phase, 0) * 60
                    if duration > planned:
                        overtime = duration - planned
                        overtime_seconds_total += overtime
                        session_has_overtime = True
                        phase_overtime[phase] = phase_overtime.get(phase, 0) + overtime

                session_pause_count += entry.get("pause_count", 0) or 0
                session_pause_duration += entry.get("total_pause_seconds", 0) or 0

            if session_has_overtime:
                overtime_count += 1
            pause_counts.append(session_pause_count)
            pause_durations.append(session_pause_duration)

        avg_durations = {}
        for phase, durations in phase_durations_sum.items():
            avg_durations[phase] = round(sum(durations) / len(durations)) if durations else 0

        most_overtime_phase = None
        if phase_overtime:
            most_overtime_phase = max(phase_overtime, key=phase_overtime.get)

        return TeacherAnalytics(
            teacher_id=teacher_id, period_start=period_start, period_end=period_end,
            total_sessions=total_sessions, completed_sessions=completed_sessions,
            total_teaching_minutes=int(total_minutes),
            avg_phase_durations=avg_durations,
            sessions_with_overtime=overtime_count,
            avg_overtime_seconds=overtime_seconds_total / max(total_sessions, 1),
            most_overtime_phase=most_overtime_phase,
            avg_pause_count=sum(pause_counts) / max(len(pause_counts), 1),
            avg_pause_duration_seconds=sum(pause_durations) / max(len(pause_durations), 1),
            subjects_taught=subjects, classes_taught=classes,
        )
