from __future__ import annotations from typing import List, Optional import aiosqlite from fastapi import APIRouter, Depends, Query, Request import ingredients import recipes import persons from common import Page, ProblemDetails from main import get_db, cookie_person, error_response # temporary imports during extraction router = APIRouter(prefix="/recipes", tags=["recipes"]) @router.get("", response_model=Page[recipes.Recipe], operation_id="listRecipes", summary="List recipes (paginated)") async def list_recipes( q: Optional[str] = Query(default=None, description="Optional case-insensitive name filter (matches recipe name with SQL LIKE)."), cursor: Optional[str] = Query(default=None, description="Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page."), limit: int = Query(50, ge=1, le=200, description="Maximum number of items to return (1-200)."), conn: aiosqlite.Connection = Depends(get_db), request: Request | None = None, ) -> Page[recipes.Recipe]: # Placeholder: implementation will be moved from main.get_recipes in a later step. raise NotImplementedError("list_recipes extraction pending") @router.get("/{recipe_id}", response_model=recipes.Recipe, operation_id="getRecipe", summary="Get a single recipe", responses={404: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}}) async def get_recipe( recipe_id: int, conn: aiosqlite.Connection = Depends(get_db), request: Request | None = None ) -> recipes.Recipe: # Placeholder: implementation will be moved from main.get_recipe in a later step. raise NotImplementedError("get_recipe extraction pending") @router.post("", response_model=recipes.Recipe, operation_id="createRecipe", summary="Create a new recipe (versioning semantics applied)", responses={400: {"model": ProblemDetails, "description": "Validation error", "content": {"application/problem+json": {}}}}) async def create_recipe( recipe: recipes.Recipe, conn: aiosqlite.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person), request: Request | None = None, ) -> recipes.Recipe: # Placeholder: implementation will be moved from main.create_recipe in a later step. raise NotImplementedError("create_recipe extraction pending") @router.delete("/{recipe_id}", response_model=recipes.Recipe, operation_id="deleteRecipe", summary="Soft-delete (hide) a recipe", responses={404: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}}) async def delete_recipe( recipe_id: int, conn: aiosqlite.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person), request: Request | None = None, ) -> recipes.Recipe: # Placeholder: implementation will be moved from main.delete_recipe in a later step. raise NotImplementedError("delete_recipe extraction pending") @router.get("/parse", response_model=None, operation_id="parseRecipe", summary="Parse a recipe from a URL", responses={400: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}}) async def parse_recipe_handler( url: str, conn: aiosqlite.Connection = Depends(get_db), person=Depends(cookie_person), request: Request | None = None ) -> recipes.Recipe: # Placeholder: implementation will be moved from main.parse_recipe_handler in a later step. raise NotImplementedError("parse_recipe_handler extraction pending") @router.get("/ingredients/parse", operation_id="parseIngredients", summary="Parse raw ingredient lines") async def parse_ingredients( lines: List[str] = Query(alias="ingredients", title="Array of ingredients to parse"), conn: aiosqlite.Connection = Depends(get_db), ) -> List[ingredients.Ingredient]: # Placeholder: implementation will be moved from main.parse_ingredients in a later step. raise NotImplementedError("parse_ingredients extraction pending")