"""Playlist management API endpoints.""" from typing import Annotated from fastapi import APIRouter, Depends from sqlmodel.ext.asyncio.session import AsyncSession from app.core.database import get_db from app.core.dependencies import get_current_active_user_flexible from app.models.user import User from app.schemas.playlist import ( PlaylistAddSoundRequest, PlaylistCreateRequest, PlaylistReorderRequest, PlaylistResponse, PlaylistSoundResponse, PlaylistStatsResponse, PlaylistUpdateRequest, ) from app.services.playlist import PlaylistService router = APIRouter(prefix="/playlists", tags=["playlists"]) async def get_playlist_service( session: Annotated[AsyncSession, Depends(get_db)], ) -> PlaylistService: """Get the playlist service.""" return PlaylistService(session) @router.get("/") async def get_all_playlists( current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> list[PlaylistResponse]: """Get all playlists from all users.""" playlists = await playlist_service.get_all_playlists() return [PlaylistResponse.from_playlist(playlist) for playlist in playlists] @router.get("/user") async def get_user_playlists( current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> list[PlaylistResponse]: """Get playlists for the current user only.""" playlists = await playlist_service.get_user_playlists(current_user.id) return [PlaylistResponse.from_playlist(playlist) for playlist in playlists] @router.get("/main") async def get_main_playlist( current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Get the global main playlist.""" playlist = await playlist_service.get_main_playlist() return PlaylistResponse.from_playlist(playlist) @router.get("/current") async def get_current_playlist( current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Get the user's current playlist (falls back to main playlist).""" playlist = await playlist_service.get_current_playlist(current_user.id) return PlaylistResponse.from_playlist(playlist) @router.post("/") async def create_playlist( request: PlaylistCreateRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Create a new playlist.""" playlist = await playlist_service.create_playlist( user_id=current_user.id, name=request.name, description=request.description, genre=request.genre, ) return PlaylistResponse.from_playlist(playlist) @router.get("/{playlist_id}") async def get_playlist( playlist_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Get a specific playlist.""" playlist = await playlist_service.get_playlist_by_id(playlist_id) return PlaylistResponse.from_playlist(playlist) @router.put("/{playlist_id}") async def update_playlist( playlist_id: int, request: PlaylistUpdateRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Update a playlist.""" playlist = await playlist_service.update_playlist( playlist_id=playlist_id, user_id=current_user.id, name=request.name, description=request.description, genre=request.genre, is_current=request.is_current, ) return PlaylistResponse.from_playlist(playlist) @router.delete("/{playlist_id}") async def delete_playlist( playlist_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> dict[str, str]: """Delete a playlist.""" await playlist_service.delete_playlist(playlist_id, current_user.id) return {"message": "Playlist deleted successfully"} @router.get("/search/{query}") async def search_playlists( query: str, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> list[PlaylistResponse]: """Search all playlists by name.""" playlists = await playlist_service.search_all_playlists(query) return [PlaylistResponse.from_playlist(playlist) for playlist in playlists] @router.get("/user/search/{query}") async def search_user_playlists( query: str, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> list[PlaylistResponse]: """Search current user's playlists by name.""" playlists = await playlist_service.search_playlists(query, current_user.id) return [PlaylistResponse.from_playlist(playlist) for playlist in playlists] @router.get("/{playlist_id}/sounds") async def get_playlist_sounds( playlist_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> list[PlaylistSoundResponse]: """Get all sounds in a playlist.""" sounds = await playlist_service.get_playlist_sounds(playlist_id) return [PlaylistSoundResponse.from_sound(sound) for sound in sounds] @router.post("/{playlist_id}/sounds") async def add_sound_to_playlist( playlist_id: int, request: PlaylistAddSoundRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> dict[str, str]: """Add a sound to a playlist.""" await playlist_service.add_sound_to_playlist( playlist_id=playlist_id, sound_id=request.sound_id, user_id=current_user.id, position=request.position, ) return {"message": "Sound added to playlist successfully"} @router.delete("/{playlist_id}/sounds/{sound_id}") async def remove_sound_from_playlist( playlist_id: int, sound_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> dict[str, str]: """Remove a sound from a playlist.""" await playlist_service.remove_sound_from_playlist( playlist_id=playlist_id, sound_id=sound_id, user_id=current_user.id, ) return {"message": "Sound removed from playlist successfully"} @router.put("/{playlist_id}/sounds/reorder") async def reorder_playlist_sounds( playlist_id: int, request: PlaylistReorderRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> dict[str, str]: """Reorder sounds in a playlist.""" await playlist_service.reorder_playlist_sounds( playlist_id=playlist_id, user_id=current_user.id, sound_positions=request.sound_positions, ) return {"message": "Playlist sounds reordered successfully"} @router.put("/{playlist_id}/set-current") async def set_current_playlist( playlist_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistResponse: """Set a playlist as the current playlist.""" playlist = await playlist_service.set_current_playlist(playlist_id, current_user.id) return PlaylistResponse.from_playlist(playlist) @router.delete("/current") async def unset_current_playlist( current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> dict[str, str]: """Unset the current playlist.""" await playlist_service.unset_current_playlist(current_user.id) return {"message": "Current playlist unset successfully"} @router.get("/{playlist_id}/stats") async def get_playlist_stats( playlist_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], playlist_service: Annotated[PlaylistService, Depends(get_playlist_service)], ) -> PlaylistStatsResponse: """Get statistics for a playlist.""" stats = await playlist_service.get_playlist_stats(playlist_id) return PlaylistStatsResponse(**stats)