from fastapi import APIRouter, Depends, HTTPException, status, Query from sqlalchemy.orm import Session from typing import List, Optional, Dict, Any from datetime import datetime from app import crud from app.models.todo import PriorityEnum as ModelPriorityEnum from app.schemas.todo import Todo, TodoCreate, TodoUpdate, PriorityEnum from app.db.base import get_db router = APIRouter() @router.get("/", response_model=List[Todo]) def read_todos( skip: int = 0, limit: int = 100, category: Optional[str] = None, priority: Optional[PriorityEnum] = None, completed: Optional[bool] = None, due_before: Optional[datetime] = None, due_after: Optional[datetime] = None, sort_by: str = "created_at", sort_desc: bool = True, db: Session = Depends(get_db) ): """ Get all todos with filtering options: - Filter by category - Filter by priority level - Filter by completion status - Filter by due date (before/after) - Sort by any field - Pagination """ todos = crud.get_todos( db=db, skip=skip, limit=limit, category=category, priority=priority.value if priority else None, completed=completed, due_before=due_before, due_after=due_after, sort_by=sort_by, sort_desc=sort_desc ) return todos @router.post("/", response_model=Todo, status_code=status.HTTP_201_CREATED) def create_todo(todo: TodoCreate, db: Session = Depends(get_db)): """Create a new todo item with extended fields""" return crud.create_todo(db=db, todo=todo) @router.get("/stats", response_model=Dict[str, Any]) def get_todo_stats(db: Session = Depends(get_db)): """Get statistics about todos""" return crud.get_todo_stats(db=db) @router.get("/{todo_id}", response_model=Todo) def read_todo(todo_id: int, db: Session = Depends(get_db)): """Get a specific todo by ID""" db_todo = crud.get_todo(db, todo_id=todo_id) if db_todo is None: raise HTTPException(status_code=404, detail="Todo not found") return db_todo @router.put("/{todo_id}", response_model=Todo) def update_todo(todo_id: int, todo: TodoUpdate, db: Session = Depends(get_db)): """Update a todo with new values including category, priority and due date""" db_todo = crud.update_todo(db=db, todo_id=todo_id, todo=todo) if db_todo is None: raise HTTPException(status_code=404, detail="Todo not found") return db_todo @router.delete("/{todo_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_todo(todo_id: int, db: Session = Depends(get_db)): """Delete a todo by ID""" success = crud.delete_todo(db=db, todo_id=todo_id) if not success: raise HTTPException(status_code=404, detail="Todo not found") return None