"""Search endpoints: global and library-scoped."""

from typing import Any

from fastapi import APIRouter, Query

from app.api.deps import AlbumRepoDep, ArtistRepoDep, CurrentUser, TrackRepoDep
from app.api.schemas.album import AlbumOut
from app.api.schemas.artist import ArtistOut
from app.api.schemas.search import LibrarySearchResponse
from app.api.schemas.track import TrackOut
from app.api.v1.albums import _build_album_out
from app.api.v1.tracks import _build_track_out

router = APIRouter(prefix="/search", tags=["search"])


@router.get("")
async def search(_: CurrentUser) -> Any: ...


@router.get("/library")
async def search_library(
    track_repo: TrackRepoDep,
    artist_repo: ArtistRepoDep,
    album_repo: AlbumRepoDep,
    _: CurrentUser,
    q: str = Query(min_length=1),
    types: str = Query(default="tracks,albums,artists"),
    limit: int = Query(20, ge=1, le=100),
) -> LibrarySearchResponse:
    requested = {t.strip() for t in types.split(",")}

    tracks_out: list[TrackOut] = []
    albums_out: list[AlbumOut] = []
    artists_out: list[ArtistOut] = []

    if "tracks" in requested:
        tracks = await track_repo.list(
            artist_id=None,
            album_id=None,
            q=q,
            sort_by="title",
            order="asc",
            limit=limit,
            offset=0,
        )
        if tracks:
            artist_ids = list({t.artist_id for t in tracks})
            album_ids = list({t.album_id for t in tracks if t.album_id is not None})
            artists_map = {a.id: a for a in await artist_repo.get_many(artist_ids)}
            albums_map = {a.id: a for a in await album_repo.get_many(album_ids)}
            tracks_out = await _build_track_out(tracks, artists_map, albums_map)

    if "albums" in requested:
        albums = await album_repo.list(artist_id=None, q=q, limit=limit, offset=0)
        if albums:
            artist_ids = list({a.artist_id for a in albums})
            artists_map = {a.id: a for a in await artist_repo.get_many(artist_ids)}
            track_counts = await album_repo.track_count_many([a.id for a in albums])
            albums_out = await _build_album_out(albums, artists_map, track_counts)

    if "artists" in requested:
        raw_artists = await artist_repo.list(q=q, limit=limit, offset=0)
        for a in raw_artists:
            album_cnt = await artist_repo.album_count(a.id)
            track_cnt = await artist_repo.track_count(a.id)
            artists_out.append(
                ArtistOut(
                    id=a.id,
                    name=a.name,
                    album_count=album_cnt,
                    track_count=track_cnt,
                    created_at=a.created_at,
                )
            )

    return LibrarySearchResponse(tracks=tracks_out, albums=albums_out, artists=artists_out)
