import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { useConfig } from '@/contexts/ConfigContext'; import { Switch } from '@/components/ui/switch'; const movieProviders = [ { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'imdb', label: 'IMDb (Cinemeta)' }, ]; const seriesProviders = [ { value: 'tvdb', label: 'TheTVDB (Recommended)' }, { value: 'tmdb', label: 'The Movie Database' }, { value: 'tvmaze', label: 'TVmaze' }, { value: 'imdb', label: 'IMDb (Cinemeta)' }, ]; const animeProviders = [ { value: 'kitsu', label: 'Kitsu (Recommended)' }, { value: 'mal', label: 'MyAnimeList' }, { value: 'tvdb', label: 'TheTVDB' }, // { value: 'tmdb', label: 'The Movie Database' }, { value: 'imdb', label: 'IMDb (Cinemeta)' }, ]; const animeIdProviders = [ { value: 'imdb', label: 'IMDb (More compatibility)' }, { value: 'kitsu', label: 'Kitsu ID (Recommended)' }, { value: 'mal', label: 'MyAnimeList ID' }, { value: 'retain', label: 'Retain Requested ID (Auto-detect)' }, ]; const tvdbSeasonTypes = [ { value: 'official', label: 'Official Order' }, { value: 'default', label: 'Aired Order (Default)' }, { value: 'dvd', label: 'DVD Order' }, { value: 'absolute', label: 'Absolute Order' }, { value: 'alternate', label: 'Alternate Order' }, { value: 'regional', label: 'Regional Order' }, ]; export function ProvidersSettings() { const { config, setConfig, hasBuiltInTvdb } = useConfig(); const isImdbForCatalog = !!config.mal?.useImdbIdForCatalogAndSearch; const hasTvdbKey = !!config.apiKeys?.tvdb?.trim() || hasBuiltInTvdb; const handleProviderChange = (type: 'movie' | 'series' | 'anime', value: string) => { setConfig(prev => ({ ...prev, providers: { ...prev.providers, [type]: value } })); }; const handleSeasonTypeChange = (value: string) => { setConfig(prev => ({ ...prev, tvdbSeasonType: value })); }; const handleMalToggle = (key: 'skipFiller' | 'skipRecap' | 'allowEpisodeMarking', checked: boolean) => { setConfig(prev => ({ ...prev, mal: { ...prev.mal, [key]: checked, } })); }; const handleMalUseImdbToggle = (checked: boolean) => { setConfig(prev => ({ ...prev, mal: { ...prev.mal, useImdbIdForCatalogAndSearch: checked, }, providers: { ...prev.providers, // If enabling, ensure MAL isn't selected as anime meta provider anime: checked && (prev.providers.anime === 'mal' || prev.providers.anime === 'kitsu') ? 'imdb' : prev.providers.anime, // No automatic switching of anime_id_provider } })); }; const handleAnimeIdProviderChange = (value: 'imdb' | 'kitsu' | 'mal') => { setConfig(prev => ({ ...prev, providers: { ...prev.providers, anime_id_provider: value } })); }; const handleTmdbToggle = (key: 'scrapeImdb' | 'forceLatinCastNames', checked: boolean) => { setConfig(prev => ({ ...prev, tmdb: { ...prev.tmdb, [key]: checked, } })); }; const handleForceAnimeToggle = (checked: boolean) => { setConfig(prev => ({ ...prev, providers: { ...prev.providers, forceAnimeForDetectedImdb: checked } })); }; return (

Metadata Providers

Choose your preferred source for metadata. Different providers may have better data for certain content.

Smart Fallback: If metadata for a title can't be found with your preferred provider (e.g., no TVDB entry for a TMDB movie), the addon will automatically use the item's original source to guarantee you get a result.

{/* Provider Selection Grid */}
Movie ProviderSource for movie data. Series ProviderSource for TV show data. Anime ProviderSource for anime data. {isImdbForCatalog && (

MAL is disabled because "Use IMDb ID for Catalog/Search" is enabled in MAL settings.

)}
{/* TVDB Specific Settings */} TheTVDB Settings {hasTvdbKey ? 'Customize how episode data is fetched from TheTVDB.' : 'Add your TVDB API key in the Integrations tab to enable these settings.'}

"Aired Order (Default)" or "Official order" are recommended.

{/* TMDB Specific Settings */} The Movie Database (TMDB) Settings Customize how data is handled when TMDB is the source. {/* Scrape IMDb Toggle */}

Automatically scrape additional data from IMDb to obtain IMDb ID when missing from TMDB. This is useful for sports events and other content that doesn't have an IMDb ID in TMDB.

handleTmdbToggle('scrapeImdb', val)} />
{/* Force Latin Cast Names */}

Fetch English TMDB cast credits even when your display language is another locale (useful for Asian productions with non-Latin character sets).

handleTmdbToggle('forceLatinCastNames', val)} />
{/* Anime Settings */} Anime Settings Configure how anime content is detected and handled across catalogs. {/* Anime Detection Override */}

When enabled, any catalog item that maps to an anime (via MAL/Kitsu/AniList/AniDB... detection) will use the Anime meta provider, even if the original catalog was non-anime.

⚠️ Note: Detected anime with IMDb IDs will use Movie/Series art providers instead of Anime art providers.

{/* Use IMDb ID for Catalog/Search */}

Prefer IMDb IDs for anime items in Anime catalogs and search (when available).

⚠️ Note: Anime in catalogs/search will use Movie/Series art providers instead of Anime art providers when this is enabled.

{/* Anime Stream Compatibility ID */}

Choose which ID format to use for anime. This affects which streaming addons will find results.

"IMDb" can improve compatibility as it is supported by most streaming addons. "Retain Requested ID" automatically uses the ID type from the request (e.g., IMDb for tt123, Kitsu for kitsu:456, MAL for mal:789). Kitsu is recommended when using MAL as meta provider.

⚠️ Using TVDB/IMDb as anime meta provider with Kitsu/MAL anime compatibility ID is considered experimental as they rely on community mappings and could contain inaccurate information.

{/* MyAnimeList Specific Settings */} MyAnimeList (MAL) Settings Customize how data is handled when MyAnimeList is the source. {/* Skip Filler Toggle */}

Automatically filter out episodes marked as filler.

handleMalToggle('skipFiller', val)} />
{/* Skip Recap Toggle */}

Automatically filter out episodes marked as recaps.

handleMalToggle('skipRecap', val)} />
{/* Allow Episode Marking Toggle */}

Enable users to mark episodes as filler or recap.

handleMalToggle('allowEpisodeMarking', val)} />
); }