from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_user from app.models.user import User from app.models.recommendation import Recommendation from app.schemas.recommendation import RecommendationRequest, RecommendationResponse, RecommendationItem from app.services.recommender import generate_recommendations router = APIRouter(prefix="/recommendations", tags=["recommendations"]) @router.post("/generate", response_model=RecommendationResponse) async def generate( data: RecommendationRequest, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): if not data.playlist_id and not data.query: raise HTTPException(status_code=400, detail="Provide a playlist_id or query") recs, remaining = await generate_recommendations( db, user, playlist_id=data.playlist_id, query=data.query ) if not recs and remaining == 0: raise HTTPException(status_code=429, detail="Daily recommendation limit reached. Upgrade to Pro for unlimited.") return RecommendationResponse( recommendations=[RecommendationItem.model_validate(r) for r in recs], remaining_today=remaining, ) @router.get("/history", response_model=list[RecommendationItem]) async def history( user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Recommendation) .where(Recommendation.user_id == user.id) .order_by(Recommendation.created_at.desc()) .limit(50) ) return result.scalars().all() @router.get("/saved", response_model=list[RecommendationItem]) async def saved( user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Recommendation) .where(Recommendation.user_id == user.id, Recommendation.saved == True) .order_by(Recommendation.created_at.desc()) ) return result.scalars().all() @router.post("/{rec_id}/save") async def save_recommendation( rec_id: int, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Recommendation).where(Recommendation.id == rec_id, Recommendation.user_id == user.id) ) rec = result.scalar_one_or_none() if not rec: raise HTTPException(status_code=404, detail="Recommendation not found") rec.saved = not rec.saved return {"saved": rec.saved}