import { getTmdbImageUrl } from '../api/tmdb' import type { BaseItemDto } from '../api/types' import type { TmdbDiscoverItem } from '../api/tmdb' /** * Convert a TMDB result row (movie / tv / multi) into a synthetic * BaseItemDto so it can render through the same PosterCard pipeline as * Jellyfin items. When a `libraryMap` (TMDB id -> Jellyfin item) is * provided, items already in the user's library are flagged via * `_inLibrary` and their `Id` is rewritten to the local Jellyfin id so * clicking opens the existing detail page instead of the synthetic one. */ export function mapTmdbToJf( items: TmdbDiscoverItem[], libraryMap?: Map, ): BaseItemDto[] { return items.map(m => { const local = libraryMap?.get(String(m.id)) const isSeries = m.media_type === 'tv' || !!m.first_air_date // Encode kind in the synthetic id so DetailPage can route directly // to the right TMDB endpoint without guessing. Library matches keep // the Jellyfin id as before. const syntheticId = `tmdb-${isSeries ? 'tv' : 'movie'}-${m.id}` return { Id: local?.id || syntheticId, Name: m.title || m.name, Type: isSeries ? 'Series' : 'Movie', ProductionYear: m.release_date ? parseInt(m.release_date) : m.first_air_date ? parseInt(m.first_air_date) : undefined, Overview: m.overview, ImageTags: {}, ProviderIds: { Tmdb: String(m.id) }, CommunityRating: typeof m.vote_average === 'number' ? m.vote_average : undefined, _tmdbPoster: m.poster_path ? getTmdbImageUrl(m.poster_path, 'w342') : undefined, _tmdbBackdrop: m.backdrop_path ? getTmdbImageUrl(m.backdrop_path, 'w780') : undefined, _inLibrary: !!local, _tmdbId: String(m.id), } as unknown as BaseItemDto }) } /** * Detect whether a route id is a synthetic TMDB id (from the discovery * rows) and parse out kind + numeric id when so. Returns null for * regular Jellyfin ids. */ export function parseTmdbRouteId(id: string | undefined | null): { kind: 'movie' | 'tv'; tmdbId: number } | null { if (!id) return null // New format: tmdb-movie-123 / tmdb-tv-123 const match = id.match(/^tmdb-(movie|tv)-(\d+)$/) if (match) { return { kind: match[1] as 'movie' | 'tv', tmdbId: Number(match[2]) } } // Legacy format: tmdb-123 (kind unknown - default to movie). Persists // until any saved data with the old id refreshes. const legacy = id.match(/^tmdb-(\d+)$/) if (legacy) return { kind: 'movie', tmdbId: Number(legacy[1]) } return null }