from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.database import get_db
from app.models.quiz import Quiz
from app.models.quiz_category import QuizCategory
from app.models.user import User
from app.utils.auth import get_current_user, require_moderator

router = APIRouter()


class CategoryCreate(BaseModel):
    name: str


class CategoryResponse(BaseModel):
    id: int
    name: str
    quiz_count: int = 0

    model_config = {"from_attributes": True}


@router.get("/", response_model=list[CategoryResponse])
def list_categories(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    cats = db.query(QuizCategory).order_by(QuizCategory.name).all()
    return [
        CategoryResponse(id=c.id, name=c.name,
                         quiz_count=db.query(Quiz).filter(Quiz.category_id == c.id).count())
        for c in cats
    ]


@router.post("/", response_model=CategoryResponse)
def create_category(
    data: CategoryCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_moderator),
):
    if not data.name.strip():
        raise HTTPException(status_code=400, detail="Category name cannot be empty")
    existing = db.query(QuizCategory).filter(QuizCategory.name == data.name.strip()).first()
    if existing:
        raise HTTPException(status_code=400, detail="Category already exists")
    cat = QuizCategory(name=data.name.strip(), user_id=current_user.id)
    db.add(cat)
    db.commit()
    db.refresh(cat)
    return CategoryResponse(id=cat.id, name=cat.name, quiz_count=0)


@router.delete("/{category_id}", status_code=204)
def delete_category(
    category_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_moderator),
):
    cat = db.query(QuizCategory).filter(QuizCategory.id == category_id).first()
    if not cat:
        raise HTTPException(status_code=404, detail="Category not found")
    # Unassign quizzes
    db.query(Quiz).filter(Quiz.category_id == category_id).update({"category_id": None})
    db.delete(cat)
    db.commit()


@router.patch("/quizzes/{quiz_id}")
def set_quiz_category(
    quiz_id: int,
    category_id: int | None = None,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_moderator),
):
    """Assign or remove a category from a quiz. Pass category_id=null to uncategorize."""
    quiz = db.query(Quiz).filter(Quiz.id == quiz_id).first()
    if not quiz:
        raise HTTPException(status_code=404, detail="Quiz not found")
    if category_id is not None:
        cat = db.query(QuizCategory).filter(QuizCategory.id == category_id).first()
        if not cat:
            raise HTTPException(status_code=404, detail="Category not found")
    quiz.category_id = category_id
    db.commit()
    return {"quiz_id": quiz_id, "category_id": category_id}
