import type { TmdbMovieResult, TmdbPersonResult, TmdbTvResult, } from '../api/themoviedb'; import { MediaType as MainMediaType } from '../constants/media'; import Media from '../entity/Media'; export type MediaType = 'tv' | 'movie' | 'person'; interface SearchResult { id: number; mediaType: MediaType; popularity: number; posterPath?: string; backdropPath?: string; voteCount: number; voteAverage: number; genreIds: number[]; overview: string; originalLanguage: string; mediaInfo?: Media; } export interface MovieResult extends SearchResult { mediaType: 'movie'; title: string; originalTitle: string; releaseDate: string; adult: boolean; video: boolean; mediaInfo?: Media; } export interface TvResult extends SearchResult { mediaType: 'tv'; name: string; originalName: string; originCountry: string[]; firstAirDate: string; } export interface PersonResult { id: number; name: string; popularity: number; profilePath?: string; adult: boolean; mediaType: 'person'; knownFor: (MovieResult | TvResult)[]; } export type Results = MovieResult | TvResult | PersonResult; export const mapMovieResult = ( movieResult: TmdbMovieResult, media?: Media ): MovieResult => ({ id: movieResult.id, mediaType: 'movie', adult: movieResult.adult, genreIds: movieResult.genre_ids, originalLanguage: movieResult.original_language, originalTitle: movieResult.original_title, overview: movieResult.overview, popularity: movieResult.popularity, releaseDate: movieResult.release_date, title: movieResult.title, video: movieResult.video, voteAverage: movieResult.vote_average, voteCount: movieResult.vote_count, backdropPath: movieResult.backdrop_path, posterPath: movieResult.poster_path, mediaInfo: media, }); export const mapTvResult = ( tvResult: TmdbTvResult, media?: Media ): TvResult => ({ id: tvResult.id, firstAirDate: tvResult.first_air_date, genreIds: tvResult.genre_ids, // Some results from tmdb dont return the mediaType so we force it here! mediaType: tvResult.media_type || 'tv', name: tvResult.name, originCountry: tvResult.origin_country, originalLanguage: tvResult.original_language, originalName: tvResult.original_name, overview: tvResult.overview, popularity: tvResult.popularity, voteAverage: tvResult.vote_average, voteCount: tvResult.vote_count, backdropPath: tvResult.backdrop_path, posterPath: tvResult.poster_path, mediaInfo: media, }); export const mapPersonResult = ( personResult: TmdbPersonResult ): PersonResult => ({ id: personResult.id, name: personResult.name, popularity: personResult.popularity, adult: personResult.adult, mediaType: personResult.media_type, profilePath: personResult.profile_path, knownFor: personResult.known_for.map((result) => { if (result.media_type === 'movie') { return mapMovieResult(result); } return mapTvResult(result); }), }); export const mapSearchResults = ( results: (TmdbMovieResult | TmdbTvResult | TmdbPersonResult)[], media?: Media[] ): Results[] => results.map((result) => { switch (result.media_type) { case 'movie': return mapMovieResult( result, media?.find( (req) => req.tmdbId === result.id && req.mediaType === MainMediaType.MOVIE ) ); case 'tv': return mapTvResult( result, media?.find( (req) => req.tmdbId === result.id && req.mediaType === MainMediaType.TV ) ); default: return mapPersonResult(result); } });