"""
Teacher Dashboard - Pydantic Models, Auth Dependency, and Service Helpers.
"""

import os
import logging
from datetime import datetime
from typing import List, Optional, Dict, Any
from enum import Enum

from fastapi import HTTPException, Request
from pydantic import BaseModel
import httpx

logger = logging.getLogger(__name__)

# Feature flags
USE_DATABASE = os.getenv("GAME_USE_DATABASE", "true").lower() == "true"
REQUIRE_AUTH = os.getenv("TEACHER_REQUIRE_AUTH", "true").lower() == "true"
SCHOOL_SERVICE_URL = os.getenv("SCHOOL_SERVICE_URL", "http://school-service:8084")


# ==============================================
# Pydantic Models
# ==============================================

class UnitAssignmentStatus(str, Enum):
    """Status of a unit assignment"""
    DRAFT = "draft"
    ACTIVE = "active"
    COMPLETED = "completed"
    ARCHIVED = "archived"


class TeacherControlSettings(BaseModel):
    """Unit settings that teachers can configure"""
    allow_skip: bool = True
    allow_replay: bool = True
    max_time_per_stop_sec: int = 90
    show_hints: bool = True
    require_precheck: bool = True
    require_postcheck: bool = True


class AssignUnitRequest(BaseModel):
    """Request to assign a unit to a class"""
    unit_id: str
    class_id: str
    due_date: Optional[datetime] = None
    settings: Optional[TeacherControlSettings] = None
    notes: Optional[str] = None


class UnitAssignment(BaseModel):
    """Unit assignment record"""
    assignment_id: str
    unit_id: str
    class_id: str
    teacher_id: str
    status: UnitAssignmentStatus
    settings: TeacherControlSettings
    due_date: Optional[datetime] = None
    notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime


class StudentUnitProgress(BaseModel):
    """Progress of a single student on a unit"""
    student_id: str
    student_name: str
    session_id: Optional[str] = None
    status: str  # "not_started", "in_progress", "completed"
    completion_rate: float = 0.0
    precheck_score: Optional[float] = None
    postcheck_score: Optional[float] = None
    learning_gain: Optional[float] = None
    time_spent_minutes: int = 0
    last_activity: Optional[datetime] = None
    current_stop: Optional[str] = None
    stops_completed: int = 0
    total_stops: int = 0


class ClassUnitProgress(BaseModel):
    """Overall progress of a class on a unit"""
    assignment_id: str
    unit_id: str
    unit_title: str
    class_id: str
    class_name: str
    total_students: int
    started_count: int
    completed_count: int
    avg_completion_rate: float
    avg_precheck_score: Optional[float] = None
    avg_postcheck_score: Optional[float] = None
    avg_learning_gain: Optional[float] = None
    avg_time_minutes: float
    students: List[StudentUnitProgress]


class MisconceptionReport(BaseModel):
    """Report of detected misconceptions"""
    concept_id: str
    concept_label: str
    misconception: str
    affected_students: List[str]
    frequency: int
    unit_id: str
    stop_id: str


class ClassAnalyticsSummary(BaseModel):
    """Summary analytics for a class"""
    class_id: str
    class_name: str
    total_units_assigned: int
    units_completed: int
    active_units: int
    avg_completion_rate: float
    avg_learning_gain: Optional[float]
    total_time_hours: float
    top_performers: List[str]
    struggling_students: List[str]
    common_misconceptions: List[MisconceptionReport]


class ContentResource(BaseModel):
    """Generated content resource"""
    resource_type: str  # "h5p", "pdf", "worksheet"
    title: str
    url: str
    generated_at: datetime
    unit_id: str


# ==============================================
# Auth Dependency
# ==============================================

async def get_current_teacher(request: Request) -> Dict[str, Any]:
    """Get current teacher from JWT token."""
    if not REQUIRE_AUTH:
        return {
            "user_id": "e9484ad9-32ee-4f2b-a4e1-d182e02ccf20",
            "email": "demo@breakpilot.app",
            "role": "teacher",
            "name": "Demo Lehrer"
        }

    auth_header = request.headers.get("Authorization", "")
    if not auth_header.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing authorization token")

    try:
        import jwt
        token = auth_header[7:]
        secret = os.getenv("JWT_SECRET", "dev-secret-key")
        payload = jwt.decode(token, secret, algorithms=["HS256"])

        if payload.get("role") not in ["teacher", "admin"]:
            raise HTTPException(status_code=403, detail="Teacher or admin role required")

        return payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expired")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")


# ==============================================
# Database Integration
# ==============================================

_teacher_db = None


async def get_teacher_database():
    """Get teacher database instance with lazy initialization."""
    global _teacher_db
    if not USE_DATABASE:
        return None
    if _teacher_db is None:
        try:
            from unit.database import get_teacher_db
            _teacher_db = await get_teacher_db()
            logger.info("Teacher database initialized")
        except ImportError:
            logger.warning("Teacher database module not available")
        except Exception as e:
            logger.warning(f"Teacher database not available: {e}")
    return _teacher_db


# ==============================================
# School Service Integration
# ==============================================

async def get_classes_for_teacher(teacher_id: str) -> List[Dict[str, Any]]:
    """Get classes assigned to a teacher from school service."""
    async with httpx.AsyncClient(timeout=10.0) as client:
        try:
            response = await client.get(
                f"{SCHOOL_SERVICE_URL}/api/v1/school/classes",
                headers={"X-Teacher-ID": teacher_id}
            )
            if response.status_code == 200:
                return response.json()
        except Exception as e:
            logger.error(f"Failed to get classes from school service: {e}")
    return []


async def get_students_in_class(class_id: str) -> List[Dict[str, Any]]:
    """Get students in a class from school service."""
    async with httpx.AsyncClient(timeout=10.0) as client:
        try:
            response = await client.get(
                f"{SCHOOL_SERVICE_URL}/api/v1/school/classes/{class_id}/students"
            )
            if response.status_code == 200:
                return response.json()
        except Exception as e:
            logger.error(f"Failed to get students from school service: {e}")
    return []
