"""Player API endpoints.""" from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, status from app.core.dependencies import get_current_active_user_flexible from app.core.logging import get_logger from app.models.user import User from app.schemas.common import MessageResponse from app.schemas.player import ( PlayerModeRequest, PlayerSeekRequest, PlayerStateResponse, PlayerVolumeRequest, ) from app.services.player import get_player_service logger = get_logger(__name__) router = APIRouter(prefix="/player", tags=["player"]) @router.post("/play") async def play( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Play current sound.""" try: player = get_player_service() await player.play() return MessageResponse(message="Playback started") except Exception as e: logger.exception("Error starting playback") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to start playback", ) from e @router.post("/play/{index}") async def play_at_index( index: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Play sound at specific index.""" try: player = get_player_service() await player.play(index) return MessageResponse(message=f"Playing sound at index {index}") except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) from e except Exception as e: logger.exception("Error playing sound at index %s", index) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to play sound", ) from e @router.post("/pause") async def pause( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Pause playback.""" try: player = get_player_service() await player.pause() return MessageResponse(message="Playback paused") except Exception as e: logger.exception("Error pausing playback") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to pause playback", ) from e @router.post("/stop") async def stop( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Stop playback.""" try: player = get_player_service() await player.stop_playback() return MessageResponse(message="Playback stopped") except Exception as e: logger.exception("Error stopping playback") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to stop playback", ) from e @router.post("/next") async def next_track( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Skip to next track.""" try: player = get_player_service() await player.next() return MessageResponse(message="Skipped to next track") except Exception as e: logger.exception("Error skipping to next track") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to skip to next track", ) from e @router.post("/previous") async def previous_track( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Go to previous track.""" try: player = get_player_service() await player.previous() return MessageResponse(message="Went to previous track") except Exception as e: logger.exception("Error going to previous track") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to go to previous track", ) from e @router.post("/seek") async def seek( request: PlayerSeekRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Seek to specific position in current track.""" try: player = get_player_service() await player.seek(request.position) return MessageResponse(message=f"Seeked to position {request.position}ms") except Exception as e: logger.exception("Error seeking to position %s", request.position) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to seek", ) from e @router.post("/volume") async def set_volume( request: PlayerVolumeRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Set playback volume.""" try: player = get_player_service() await player.set_volume(request.volume) return MessageResponse(message=f"Volume set to {request.volume}") except Exception as e: logger.exception("Error setting volume to %s", request.volume) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to set volume", ) from e @router.post("/mute") async def mute( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Mute playback.""" try: player = get_player_service() await player.mute() return MessageResponse(message="Playback muted") except Exception as e: logger.exception("Error muting playback") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to mute playback", ) from e @router.post("/unmute") async def unmute( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Unmute playback.""" try: player = get_player_service() await player.unmute() return MessageResponse(message="Playback unmuted") except Exception as e: logger.exception("Error unmuting playback") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to unmute playback", ) from e @router.post("/mode") async def set_mode( request: PlayerModeRequest, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Set playback mode.""" try: player = get_player_service() await player.set_mode(request.mode) return MessageResponse(message=f"Mode set to {request.mode.value}") except Exception as e: logger.exception("Error setting mode to %s", request.mode) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to set mode", ) from e @router.post("/reload-playlist") async def reload_playlist( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Reload current playlist.""" try: player = get_player_service() await player.reload_playlist() return MessageResponse(message="Playlist reloaded") except Exception as e: logger.exception("Error reloading playlist") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to reload playlist", ) from e @router.get("/state") async def get_state( current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> PlayerStateResponse: """Get current player state.""" try: player = get_player_service() state = player.get_state() return PlayerStateResponse(**state) except Exception as e: logger.exception("Error getting player state") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to get player state", ) from e @router.post("/play-next/{sound_id}") async def add_to_play_next( sound_id: int, current_user: Annotated[User, Depends(get_current_active_user_flexible)], # noqa: ARG001 ) -> MessageResponse: """Add a sound to the play next queue.""" try: player = get_player_service() await player.add_to_play_next(sound_id) return MessageResponse(message=f"Added sound {sound_id} to play next queue") except Exception as e: logger.exception("Error adding sound to play next queue: %s", sound_id) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to add sound to play next queue", ) from e