"""Track management endpoints."""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from uuid import UUID

from ...models.database import get_db
from ...models import crud
from ...models.schema import AudioTrack

router = APIRouter()


@router.get("", response_model=dict)
async def get_tracks(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    genre: Optional[str] = None,
    mood: Optional[str] = None,
    bpm_min: Optional[float] = Query(None, ge=0, le=300),
    bpm_max: Optional[float] = Query(None, ge=0, le=300),
    energy_min: Optional[float] = Query(None, ge=0, le=1),
    energy_max: Optional[float] = Query(None, ge=0, le=1),
    has_vocals: Optional[bool] = None,
    key: Optional[str] = None,
    instrument: Optional[str] = None,
    instruments: Optional[List[str]] = Query(None),
    instruments_exclusive: bool = False,
    tempo_range: Optional[str] = Query(None, regex="^(slow|medium|fast)$"),
    sort_by: str = Query("analyzed_at", regex="^(analyzed_at|tempo_bpm|duration_seconds|filename|energy|random)$"),
    sort_desc: bool = True,
    db: Session = Depends(get_db),
):
    """Get tracks with filters and pagination.

    Args:
        skip: Number of records to skip
        limit: Maximum number of records
        genre: Filter by genre
        mood: Filter by mood
        bpm_min: Minimum BPM
        bpm_max: Maximum BPM
        energy_min: Minimum energy
        energy_max: Maximum energy
        has_vocals: Filter by vocal presence
        key: Filter by musical key
        instrument: Filter by instrument (deprecated, use instruments)
        instruments: Filter by multiple instruments (must have ALL)
        instruments_exclusive: If True, track must have ONLY the specified instruments
        tempo_range: Filter by tempo range (slow: <100, medium: 100-140, fast: >140)
        sort_by: Field to sort by (use 'random' for random order)
        sort_desc: Sort descending
        db: Database session

    Returns:
        Paginated list of tracks with total count
    """
    # Convert tempo_range to bpm_min/bpm_max
    if tempo_range:
        if tempo_range == "slow":
            bpm_max = 100.0 if bpm_max is None else min(bpm_max, 100.0)
        elif tempo_range == "medium":
            bpm_min = 100.0 if bpm_min is None else max(bpm_min, 100.0)
            bpm_max = 140.0 if bpm_max is None else min(bpm_max, 140.0)
        elif tempo_range == "fast":
            bpm_min = 140.0 if bpm_min is None else max(bpm_min, 140.0)

    # Use instruments if provided, otherwise fall back to instrument
    final_instruments = instruments if instruments else ([instrument] if instrument else None)

    tracks, total = crud.get_tracks(
        db=db,
        skip=skip,
        limit=limit,
        genre=genre,
        mood=mood,
        bpm_min=bpm_min,
        bpm_max=bpm_max,
        energy_min=energy_min,
        energy_max=energy_max,
        has_vocals=has_vocals,
        key=key,
        instruments=final_instruments,
        instruments_exclusive=instruments_exclusive,
        sort_by=sort_by,
        sort_desc=sort_desc,
    )

    return {
        "tracks": [track.to_dict() for track in tracks],
        "total": total,
        "skip": skip,
        "limit": limit,
    }


@router.get("/{track_id}")
async def get_track(
    track_id: UUID,
    db: Session = Depends(get_db),
):
    """Get track by ID.

    Args:
        track_id: Track UUID
        db: Database session

    Returns:
        Track details

    Raises:
        HTTPException: 404 if track not found
    """
    track = crud.get_track_by_id(db, track_id)

    if not track:
        raise HTTPException(status_code=404, detail="Track not found")

    return track.to_dict()


@router.delete("/{track_id}")
async def delete_track(
    track_id: UUID,
    db: Session = Depends(get_db),
):
    """Delete track by ID.

    Args:
        track_id: Track UUID
        db: Database session

    Returns:
        Success message

    Raises:
        HTTPException: 404 if track not found
    """
    success = crud.delete_track(db, track_id)

    if not success:
        raise HTTPException(status_code=404, detail="Track not found")

    return {"message": "Track deleted successfully", "track_id": str(track_id)}
