import { ref, watch } from 'vue' import { mockFilms } from '@/mocks/films' import { mockSongs } from '@/mocks/songs' import { mockPodcasts } from '@/mocks/podcasts' export interface SearchResult { type: 'film' | 'song' | 'podcast' title: string subtitle: string id: string data: unknown } const query = ref('') const results = ref([]) const isSearching = ref(false) let debounceTimer: ReturnType | null = null function searchLibrary(q: string): SearchResult[] { const lower = q.toLowerCase() const matched: SearchResult[] = [] for (const film of mockFilms) { if ( film.title.toLowerCase().includes(lower) || film.director.toLowerCase().includes(lower) || film.genres.some(g => g.toLowerCase().includes(lower)) ) { matched.push({ type: 'film', title: film.title, subtitle: `${film.year} ยท ${film.director}`, id: film.id, data: film, }) } } for (const song of mockSongs) { if ( song.title.toLowerCase().includes(lower) || song.artist.toLowerCase().includes(lower) || (song.album ?? '').toLowerCase().includes(lower) ) { matched.push({ type: 'song', title: song.title, subtitle: song.artist, id: song.id, data: song, }) } } for (const podcast of mockPodcasts) { if ( podcast.title.toLowerCase().includes(lower) || (podcast.host ?? '').toLowerCase().includes(lower) ) { matched.push({ type: 'podcast', title: podcast.title, subtitle: podcast.host ?? 'Unknown', id: podcast.id, data: podcast, }) } } return matched.slice(0, 20) } export function useFederatedSearch() { function search(q: string) { query.value = q } function clear() { query.value = '' results.value = [] isSearching.value = false } watch(query, (q) => { if (debounceTimer) clearTimeout(debounceTimer) if (!q.trim()) { results.value = [] isSearching.value = false return } isSearching.value = true debounceTimer = setTimeout(() => { results.value = searchLibrary(q.trim()) isSearching.value = false }, 150) }) return { query, results, isSearching, search, clear, } }