# ==============================================
# Teacher Dashboard - Analytics & Progress Routes
# ==============================================

from fastapi import APIRouter, HTTPException, Query, Depends, Request
from typing import List, Optional, Dict, Any
from datetime import datetime, timedelta
import logging

from .models import (
    UnitAssignmentStatus, TeacherControlSettings,
    UnitAssignment, StudentUnitProgress, ClassUnitProgress,
    MisconceptionReport, ClassAnalyticsSummary, ContentResource,
    get_current_teacher, get_teacher_database,
    get_classes_for_teacher, get_students_in_class,
    REQUIRE_AUTH,
)

logger = logging.getLogger(__name__)

router = APIRouter(tags=["Teacher Dashboard"])

# Shared in-memory store reference (set from teacher_dashboard_api)
_assignments_store: Dict[str, Dict[str, Any]] = {}


def set_assignments_store(store: Dict[str, Dict[str, Any]]):
    """Share the in-memory assignments store from the main module."""
    global _assignments_store
    _assignments_store = store


# ==============================================
# API Endpoints - Progress & Analytics
# ==============================================

@router.get("/assignments/{assignment_id}/progress", response_model=ClassUnitProgress)
async def get_assignment_progress(
    assignment_id: str,
    teacher: Dict[str, Any] = Depends(get_current_teacher)
) -> ClassUnitProgress:
    """Get detailed progress for an assignment."""
    db = await get_teacher_database()
    assignment = None
    if db:
        try:
            assignment = await db.get_assignment(assignment_id)
        except Exception as e:
            logger.error(f"Failed to get assignment: {e}")
    if not assignment and assignment_id in _assignments_store:
        assignment = _assignments_store[assignment_id]
    if not assignment or assignment["teacher_id"] != teacher["user_id"]:
        raise HTTPException(status_code=404, detail="Assignment not found")

    students = await get_students_in_class(assignment["class_id"])
    student_progress = []
    total_completion = 0.0
    total_precheck = 0.0
    total_postcheck = 0.0
    total_time = 0
    precheck_count = 0
    postcheck_count = 0
    started = 0
    completed = 0

    for student in students:
        student_id = student.get("id", student.get("student_id"))
        progress = StudentUnitProgress(
            student_id=student_id,
            student_name=student.get("name", f"Student {student_id[:8]}"),
            status="not_started", completion_rate=0.0, stops_completed=0, total_stops=0,
        )
        if db:
            try:
                session_data = await db.get_student_unit_session(
                    student_id=student_id, unit_id=assignment["unit_id"]
                )
                if session_data:
                    progress.session_id = session_data.get("session_id")
                    progress.status = "completed" if session_data.get("completed_at") else "in_progress"
                    progress.completion_rate = session_data.get("completion_rate", 0.0)
                    progress.precheck_score = session_data.get("precheck_score")
                    progress.postcheck_score = session_data.get("postcheck_score")
                    progress.time_spent_minutes = session_data.get("duration_seconds", 0) // 60
                    progress.last_activity = session_data.get("updated_at")
                    progress.stops_completed = session_data.get("stops_completed", 0)
                    progress.total_stops = session_data.get("total_stops", 0)
                    if progress.precheck_score is not None and progress.postcheck_score is not None:
                        progress.learning_gain = progress.postcheck_score - progress.precheck_score
                    total_completion += progress.completion_rate
                    total_time += progress.time_spent_minutes
                    if progress.precheck_score is not None:
                        total_precheck += progress.precheck_score
                        precheck_count += 1
                    if progress.postcheck_score is not None:
                        total_postcheck += progress.postcheck_score
                        postcheck_count += 1
                    if progress.status != "not_started":
                        started += 1
                    if progress.status == "completed":
                        completed += 1
            except Exception as e:
                logger.error(f"Failed to get student progress: {e}")
        student_progress.append(progress)

    total_students = len(students) or 1
    return ClassUnitProgress(
        assignment_id=assignment_id, unit_id=assignment["unit_id"],
        unit_title=f"Unit {assignment['unit_id']}", class_id=assignment["class_id"],
        class_name=f"Class {assignment['class_id'][:8]}", total_students=len(students),
        started_count=started, completed_count=completed,
        avg_completion_rate=total_completion / total_students,
        avg_precheck_score=total_precheck / precheck_count if precheck_count > 0 else None,
        avg_postcheck_score=total_postcheck / postcheck_count if postcheck_count > 0 else None,
        avg_learning_gain=(total_postcheck / postcheck_count - total_precheck / precheck_count)
            if precheck_count > 0 and postcheck_count > 0 else None,
        avg_time_minutes=total_time / started if started > 0 else 0,
        students=student_progress,
    )


@router.get("/classes/{class_id}/analytics", response_model=ClassAnalyticsSummary)
async def get_class_analytics(
    class_id: str,
    teacher: Dict[str, Any] = Depends(get_current_teacher)
) -> ClassAnalyticsSummary:
    """Get summary analytics for a class."""
    db = await get_teacher_database()
    assignments = []
    if db:
        try:
            assignments = await db.list_assignments(teacher_id=teacher["user_id"], class_id=class_id)
        except Exception as e:
            logger.error(f"Failed to list assignments: {e}")
    if not assignments:
        assignments = [
            a for a in _assignments_store.values()
            if a["class_id"] == class_id and a["teacher_id"] == teacher["user_id"]
        ]

    total_units = len(assignments)
    completed_units = sum(1 for a in assignments if a.get("status") == "completed")
    active_units = sum(1 for a in assignments if a.get("status") == "active")

    students = await get_students_in_class(class_id)
    student_scores = {}
    misconceptions = []
    if db:
        try:
            for student in students:
                student_id = student.get("id", student.get("student_id"))
                analytics = await db.get_student_analytics(student_id)
                if analytics:
                    student_scores[student_id] = {
                        "name": student.get("name", student_id[:8]),
                        "avg_score": analytics.get("avg_postcheck_score", 0),
                        "total_time": analytics.get("total_time_minutes", 0),
                    }
            misconceptions_data = await db.get_class_misconceptions(class_id)
            for m in misconceptions_data:
                misconceptions.append(MisconceptionReport(
                    concept_id=m["concept_id"], concept_label=m["concept_label"],
                    misconception=m["misconception"], affected_students=m["affected_students"],
                    frequency=m["frequency"], unit_id=m["unit_id"], stop_id=m["stop_id"],
                ))
        except Exception as e:
            logger.error(f"Failed to aggregate analytics: {e}")

    sorted_students = sorted(student_scores.items(), key=lambda x: x[1]["avg_score"], reverse=True)
    top_performers = [s[1]["name"] for s in sorted_students[:3]]
    struggling_students = [s[1]["name"] for s in sorted_students[-3:] if s[1]["avg_score"] < 0.6]
    total_time = sum(s["total_time"] for s in student_scores.values())
    avg_scores = [s["avg_score"] for s in student_scores.values() if s["avg_score"] > 0]
    avg_completion = sum(avg_scores) / len(avg_scores) if avg_scores else 0

    return ClassAnalyticsSummary(
        class_id=class_id, class_name=f"Klasse {class_id[:8]}",
        total_units_assigned=total_units, units_completed=completed_units,
        active_units=active_units, avg_completion_rate=avg_completion,
        avg_learning_gain=None, total_time_hours=total_time / 60,
        top_performers=top_performers, struggling_students=struggling_students,
        common_misconceptions=misconceptions[:5],
    )


@router.get("/students/{student_id}/progress")
async def get_student_progress(
    student_id: str,
    teacher: Dict[str, Any] = Depends(get_current_teacher)
) -> Dict[str, Any]:
    """Get detailed progress for a specific student."""
    db = await get_teacher_database()
    if db:
        try:
            progress = await db.get_student_full_progress(student_id)
            return progress
        except Exception as e:
            logger.error(f"Failed to get student progress: {e}")
    return {
        "student_id": student_id, "units_attempted": 0, "units_completed": 0,
        "avg_score": 0.0, "total_time_minutes": 0, "sessions": [],
    }


# ==============================================
# API Endpoints - Content Resources
# ==============================================

@router.get("/assignments/{assignment_id}/resources", response_model=List[ContentResource])
async def get_assignment_resources(
    assignment_id: str,
    teacher: Dict[str, Any] = Depends(get_current_teacher),
    request: Request = None
) -> List[ContentResource]:
    """Get generated content resources for an assignment."""
    db = await get_teacher_database()
    assignment = None
    if db:
        try:
            assignment = await db.get_assignment(assignment_id)
        except Exception as e:
            logger.error(f"Failed to get assignment: {e}")
    if not assignment and assignment_id in _assignments_store:
        assignment = _assignments_store[assignment_id]
    if not assignment or assignment["teacher_id"] != teacher["user_id"]:
        raise HTTPException(status_code=404, detail="Assignment not found")

    unit_id = assignment["unit_id"]
    base_url = str(request.base_url).rstrip("/") if request else "http://localhost:8000"
    return [
        ContentResource(resource_type="h5p", title=f"{unit_id} - H5P Aktivitaeten",
                        url=f"{base_url}/api/units/content/{unit_id}/h5p",
                        generated_at=datetime.utcnow(), unit_id=unit_id),
        ContentResource(resource_type="worksheet", title=f"{unit_id} - Arbeitsblatt (HTML)",
                        url=f"{base_url}/api/units/content/{unit_id}/worksheet",
                        generated_at=datetime.utcnow(), unit_id=unit_id),
        ContentResource(resource_type="pdf", title=f"{unit_id} - Arbeitsblatt (PDF)",
                        url=f"{base_url}/api/units/content/{unit_id}/worksheet.pdf",
                        generated_at=datetime.utcnow(), unit_id=unit_id),
    ]


@router.post("/assignments/{assignment_id}/regenerate-content")
async def regenerate_content(
    assignment_id: str,
    resource_type: str = Query("all", description="h5p, pdf, or all"),
    teacher: Dict[str, Any] = Depends(get_current_teacher)
) -> Dict[str, Any]:
    """Trigger regeneration of content resources."""
    db = await get_teacher_database()
    assignment = None
    if db:
        try:
            assignment = await db.get_assignment(assignment_id)
        except Exception as e:
            logger.error(f"Failed to get assignment: {e}")
    if not assignment and assignment_id in _assignments_store:
        assignment = _assignments_store[assignment_id]
    if not assignment or assignment["teacher_id"] != teacher["user_id"]:
        raise HTTPException(status_code=404, detail="Assignment not found")

    logger.info(f"Content regeneration triggered for {assignment['unit_id']}: {resource_type}")
    return {
        "status": "queued", "assignment_id": assignment_id,
        "unit_id": assignment["unit_id"], "resource_type": resource_type,
        "message": "Content regeneration has been queued",
    }
