"""
Classroom API - Homework Endpoints.

Endpoints fuer Hausaufgaben-Tracking (Feature f20).
"""

from uuid import uuid4
from typing import Dict, List, Optional
from datetime import datetime
import logging

from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel, Field

from classroom_engine import Homework, HomeworkStatus

from .shared import init_db_if_needed, DB_ENABLED, logger

try:
    from classroom_engine.database import SessionLocal
    from classroom_engine.repository import HomeworkRepository
except ImportError:
    pass

router = APIRouter(tags=["Homework"])

# In-Memory Storage (Fallback)
_homework: Dict[str, Homework] = {}


# === Pydantic Models ===

class CreateHomeworkRequest(BaseModel):
    """Request zum Erstellen einer Hausaufgabe."""
    teacher_id: str
    class_id: str
    subject: str
    title: str = Field(..., max_length=300)
    description: str = ""
    session_id: Optional[str] = None
    due_date: Optional[str] = Field(None, description="ISO-Format Datum")


class UpdateHomeworkRequest(BaseModel):
    """Request zum Aktualisieren einer Hausaufgabe."""
    title: Optional[str] = Field(None, max_length=300)
    description: Optional[str] = None
    due_date: Optional[str] = None
    status: Optional[str] = None


class HomeworkResponse(BaseModel):
    """Response fuer eine Hausaufgabe."""
    homework_id: str
    teacher_id: str
    class_id: str
    subject: str
    title: str
    description: str
    session_id: Optional[str]
    due_date: Optional[str]
    status: str
    is_overdue: bool
    created_at: Optional[str]
    updated_at: Optional[str]


class HomeworkListResponse(BaseModel):
    """Response fuer Liste von Hausaufgaben."""
    homework: List[HomeworkResponse]
    total: int


# === Helper Functions ===

def build_homework_response(hw: Homework) -> HomeworkResponse:
    """Baut eine HomeworkResponse aus einem Homework-Objekt."""
    return HomeworkResponse(
        homework_id=hw.homework_id,
        teacher_id=hw.teacher_id,
        class_id=hw.class_id,
        subject=hw.subject,
        title=hw.title,
        description=hw.description,
        session_id=hw.session_id,
        due_date=hw.due_date.isoformat() if hw.due_date else None,
        status=hw.status.value,
        is_overdue=hw.is_overdue,
        created_at=hw.created_at.isoformat() if hw.created_at else None,
        updated_at=hw.updated_at.isoformat() if hw.updated_at else None,
    )


# === Endpoints ===

@router.post("/homework", response_model=HomeworkResponse, status_code=201)
async def create_homework(request: CreateHomeworkRequest) -> HomeworkResponse:
    """Erstellt eine neue Hausaufgabe (Feature f20)."""
    init_db_if_needed()

    due_date = None
    if request.due_date:
        try:
            due_date = datetime.fromisoformat(request.due_date.replace('Z', '+00:00'))
        except ValueError:
            raise HTTPException(status_code=400, detail="Ungueltiges Datumsformat")

    homework = Homework(
        homework_id=str(uuid4()),
        teacher_id=request.teacher_id,
        class_id=request.class_id,
        subject=request.subject,
        title=request.title,
        description=request.description,
        session_id=request.session_id,
        due_date=due_date,
        status=HomeworkStatus.ASSIGNED,
        created_at=datetime.utcnow(),
    )

    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            repo.create(homework)
            db.close()
        except Exception as e:
            logger.warning(f"DB persist failed for homework: {e}")

    _homework[homework.homework_id] = homework
    return build_homework_response(homework)


@router.get("/homework", response_model=HomeworkListResponse)
async def list_homework(
    teacher_id: str = Query(...),
    class_id: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    include_completed: bool = Query(False),
    limit: int = Query(50, ge=1, le=100)
) -> HomeworkListResponse:
    """Listet Hausaufgaben eines Lehrers (Feature f20)."""
    init_db_if_needed()

    homework_list = []

    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            if class_id:
                db_homework = repo.get_by_class(class_id, teacher_id, include_completed, limit)
            else:
                db_homework = repo.get_by_teacher(teacher_id, status, limit)

            for db_hw in db_homework:
                hw = repo.to_dataclass(db_hw)
                _homework[hw.homework_id] = hw
                homework_list.append(build_homework_response(hw))
            db.close()
            return HomeworkListResponse(homework=homework_list, total=len(homework_list))
        except Exception as e:
            logger.warning(f"DB read failed for homework: {e}")

    for hw in _homework.values():
        if hw.teacher_id != teacher_id:
            continue
        if class_id and hw.class_id != class_id:
            continue
        if status and hw.status.value != status:
            continue
        if not include_completed and hw.status == HomeworkStatus.COMPLETED:
            continue
        homework_list.append(build_homework_response(hw))

    return HomeworkListResponse(homework=homework_list[:limit], total=len(homework_list))


@router.get("/homework/{homework_id}", response_model=HomeworkResponse)
async def get_homework(homework_id: str) -> HomeworkResponse:
    """Ruft eine einzelne Hausaufgabe ab (Feature f20)."""
    init_db_if_needed()

    if homework_id in _homework:
        return build_homework_response(_homework[homework_id])

    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            db_hw = repo.get_by_id(homework_id)
            db.close()
            if db_hw:
                hw = repo.to_dataclass(db_hw)
                _homework[hw.homework_id] = hw
                return build_homework_response(hw)
        except Exception as e:
            logger.warning(f"DB read failed: {e}")

    raise HTTPException(status_code=404, detail="Hausaufgabe nicht gefunden")


@router.put("/homework/{homework_id}", response_model=HomeworkResponse)
async def update_homework(homework_id: str, request: UpdateHomeworkRequest) -> HomeworkResponse:
    """Aktualisiert eine Hausaufgabe (Feature f20)."""
    init_db_if_needed()

    homework = _homework.get(homework_id)

    if not homework and DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            db_hw = repo.get_by_id(homework_id)
            db.close()
            if db_hw:
                homework = repo.to_dataclass(db_hw)
                _homework[homework.homework_id] = homework
        except Exception as e:
            logger.warning(f"DB read failed: {e}")

    if not homework:
        raise HTTPException(status_code=404, detail="Hausaufgabe nicht gefunden")

    if request.title is not None:
        homework.title = request.title
    if request.description is not None:
        homework.description = request.description
    if request.due_date is not None:
        try:
            homework.due_date = datetime.fromisoformat(request.due_date.replace('Z', '+00:00'))
        except ValueError:
            raise HTTPException(status_code=400, detail="Ungueltiges Datumsformat")
    if request.status is not None:
        try:
            homework.status = HomeworkStatus(request.status)
        except ValueError:
            raise HTTPException(status_code=400, detail="Ungueltiger Status")

    homework.updated_at = datetime.utcnow()

    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            repo.update(homework)
            db.close()
        except Exception as e:
            logger.warning(f"DB update failed: {e}")

    _homework[homework_id] = homework
    return build_homework_response(homework)


@router.patch("/homework/{homework_id}/status")
async def update_homework_status(
    homework_id: str,
    status: str = Query(...)
) -> HomeworkResponse:
    """Aktualisiert nur den Status einer Hausaufgabe (Feature f20)."""
    return await update_homework(homework_id, UpdateHomeworkRequest(status=status))


@router.delete("/homework/{homework_id}")
async def delete_homework(homework_id: str) -> Dict[str, str]:
    """Loescht eine Hausaufgabe (Feature f20)."""
    init_db_if_needed()

    if homework_id in _homework:
        del _homework[homework_id]

    if DB_ENABLED:
        try:
            db = SessionLocal()
            repo = HomeworkRepository(db)
            repo.delete(homework_id)
            db.close()
        except Exception as e:
            logger.warning(f"DB delete failed: {e}")

    return {"status": "deleted", "homework_id": homework_id}
