"""Assembles Collection/franchise API responses from repository data.""" from __future__ import annotations import uuid from sqlalchemy.ext.asyncio import AsyncSession from app.core.ids import aurora_id, parse_aurora_id from app.models.enums import ArtworkType from app.repositories import collection_repository, polymorphic from app.schemas.collection import CollectionDetailOut from app.schemas.common import CollectionBriefOut from app.services.common import primary_artwork_path from app.services.movie_service import build_movie_summaries from app.services.tv_service import build_series_summaries class CollectionNotFoundError(Exception): pass def _resolve_collection_id(aid: str) -> uuid.UUID: try: return uuid.UUID(parse_aurora_id(aid, expected_type="collection")) except ValueError as exc: raise CollectionNotFoundError(str(exc)) from exc async def get_collection_detail( session: AsyncSession, collection_aurora_id: str ) -> CollectionDetailOut: collection_id = _resolve_collection_id(collection_aurora_id) collection = await collection_repository.get_collection_by_id(session, collection_id) if collection is None: raise CollectionNotFoundError(collection_aurora_id) movies = await collection_repository.get_collection_movies(session, collection_id) series = await collection_repository.get_collection_series(session, collection_id) posters = await polymorphic.get_artwork(session, "collection", collection_id, ArtworkType.POSTER) backdrops = await polymorphic.get_artwork( session, "collection", collection_id, ArtworkType.BACKDROP ) return CollectionDetailOut( id=aurora_id("collection", str(collection.id)), name=collection.name, overview=collection.overview, poster_path=primary_artwork_path(posters, ArtworkType.POSTER), backdrop_path=primary_artwork_path(backdrops, ArtworkType.BACKDROP), movies=await build_movie_summaries(session, [m.id for m in movies]), series=await build_series_summaries(session, [s.id for s in series]), created_at=collection.created_at, updated_at=collection.updated_at, ) async def build_collection_summary( session: AsyncSession, collection_id: uuid.UUID ) -> CollectionBriefOut | None: collection = await collection_repository.get_collection_by_id(session, collection_id) if collection is None: return None return CollectionBriefOut(id=aurora_id("collection", str(collection.id)), name=collection.name) async def build_collection_summaries( session: AsyncSession, collection_ids: list[uuid.UUID] ) -> list[CollectionBriefOut]: out: list[CollectionBriefOut] = [] for collection_id in collection_ids: summary = await build_collection_summary(session, collection_id) if summary is not None: out.append(summary) return out