from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from typing import List, Optional from datetime import date from app.core.database import get_db from app.core.security import decode_access_token from app.models.task import Task from app.schemas.task import TaskCreate, TaskResponse, TaskUpdate router = APIRouter() security = HTTPBearer() def get_current_user_id(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str: """Extrai user_id do token JWT""" token = credentials.credentials payload = decode_access_token(token) if not payload: raise HTTPException(status_code=401, detail="Token inválido") return payload.get("sub") @router.post("/", response_model=TaskResponse, status_code=status.HTTP_201_CREATED) async def create_task( task_data: TaskCreate, user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Criar nova tarefa""" new_task = Task( user_id=user_id, title=task_data.title, description=task_data.description, priority=task_data.priority, status=task_data.status, due_date=task_data.due_date, due_time=task_data.due_time, category_id=task_data.category_id ) db.add(new_task) db.commit() db.refresh(new_task) return new_task @router.get("/", response_model=List[TaskResponse]) async def list_tasks( user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db), status_filter: Optional[str] = None, include_archived: bool = False ): """Listar todas as tarefas do usuário""" query = db.query(Task).filter(Task.user_id == user_id) if not include_archived: query = query.filter(Task.is_archived == False) if status_filter: query = query.filter(Task.status == status_filter) tasks = query.order_by(Task.due_date.asc()).all() return tasks @router.get("/today", response_model=List[TaskResponse]) async def get_today_tasks( user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Obter tarefas de hoje""" today = date.today() tasks = db.query(Task).filter( Task.user_id == user_id, Task.due_date == today, Task.is_archived == False ).order_by(Task.due_time.asc()).all() return tasks @router.get("/{task_id}", response_model=TaskResponse) async def get_task( task_id: str, user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Obter tarefa específica""" task = db.query(Task).filter( Task.id == task_id, Task.user_id == user_id ).first() if not task: raise HTTPException(status_code=404, detail="Tarefa não encontrada") return task @router.put("/{task_id}", response_model=TaskResponse) async def update_task( task_id: str, task_data: TaskUpdate, user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Atualizar tarefa""" task = db.query(Task).filter( Task.id == task_id, Task.user_id == user_id ).first() if not task: raise HTTPException(status_code=404, detail="Tarefa não encontrada") # Atualizar campos update_data = task_data.dict(exclude_unset=True) for field, value in update_data.items(): setattr(task, field, value) db.commit() db.refresh(task) return task @router.patch("/{task_id}/status") async def update_task_status( task_id: str, status: str, user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Atualizar status da tarefa""" task = db.query(Task).filter( Task.id == task_id, Task.user_id == user_id ).first() if not task: raise HTTPException(status_code=404, detail="Tarefa não encontrada") task.status = status db.commit() return {"message": "Status atualizado", "status": status} @router.delete("/{task_id}") async def delete_task( task_id: str, user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Deletar tarefa""" task = db.query(Task).filter( Task.id == task_id, Task.user_id == user_id ).first() if not task: raise HTTPException(status_code=404, detail="Tarefa não encontrada") db.delete(task) db.commit() return {"message": "Tarefa deletada com sucesso"} @router.get("/stats/summary") async def get_task_stats( user_id: str = Depends(get_current_user_id), db: Session = Depends(get_db) ): """Estatísticas de tarefas""" from sqlalchemy import func total_tasks = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.is_archived == False ).scalar() pending = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.status == "pending", Task.is_archived == False ).scalar() in_progress = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.status == "in_progress", Task.is_archived == False ).scalar() completed = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.status == "completed", Task.is_archived == False ).scalar() today = date.today() today_tasks = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.due_date == today, Task.is_archived == False ).scalar() today_completed = db.query(func.count(Task.id)).filter( Task.user_id == user_id, Task.due_date == today, Task.status == "completed" ).scalar() return { "total_tasks": total_tasks, "pending": pending, "in_progress": in_progress, "completed": completed, "today_tasks": today_tasks, "today_completed": today_completed }