import { useState, useEffect } from 'react'; import { supabase } from '@/lib/supabaseClient'; import { TechnicalSpecFilter, CoasterStatFilter } from '@/components/search/AdvancedRideFilters'; import { useDebounce } from './useDebounce'; import { handleError } from '@/lib/errorHandler'; interface AdvancedSearchOptions { query?: string; category?: string; manufacturer?: string; technicalSpecFilters?: TechnicalSpecFilter[]; coasterStatFilters?: CoasterStatFilter[]; speedMin?: number; speedMax?: number; heightMin?: number; heightMax?: number; limit?: number; } export function useAdvancedRideSearch(options: AdvancedSearchOptions) { const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const debouncedQuery = useDebounce(options.query || '', 300); useEffect(() => { const performSearch = async () => { if (!debouncedQuery && !options.category && !options.manufacturer && (!options.technicalSpecFilters || options.technicalSpecFilters.length === 0) && (!options.coasterStatFilters || options.coasterStatFilters.length === 0)) { setResults([]); return; } setLoading(true); setError(null); try { let query = supabase .from('rides') .select(` *, parks!inner(id, name, slug), companies!rides_manufacturer_id_fkey(id, name, slug) `); // Basic text search if (debouncedQuery) { query = query.or(`name.ilike.%${debouncedQuery}%,description.ilike.%${debouncedQuery}%`); } // Category filter if (options.category) { query = query.eq('category', options.category); } // Manufacturer filter if (options.manufacturer) { query = query.eq('manufacturer_id', options.manufacturer); } // Speed range filter if (options.speedMin !== undefined) { query = query.gte('max_speed_kmh', options.speedMin); } if (options.speedMax !== undefined) { query = query.lte('max_speed_kmh', options.speedMax); } // Height range filter if (options.heightMin !== undefined) { query = query.gte('max_height_meters', options.heightMin); } if (options.heightMax !== undefined) { query = query.lte('max_height_meters', options.heightMax); } query = query.limit(options.limit || 50); const { data: initialResults, error: queryError } = await query; if (queryError) throw queryError; let filteredResults = initialResults || []; // Apply technical specification filters if (options.technicalSpecFilters && options.technicalSpecFilters.length > 0) { for (const filter of options.technicalSpecFilters) { if (!filter.spec_name) continue; const { data: specsData, error: specsError } = await supabase .from('ride_technical_specifications') .select('ride_id, spec_name, spec_value') .eq('spec_name', filter.spec_name); if (specsError) throw specsError; const matchingRideIds = new Set(); specsData?.forEach((spec) => { let matches = false; switch (filter.operator) { case 'has_spec': matches = true; break; case 'equals': matches = spec.spec_value === filter.spec_value; break; case 'contains': matches = filter.spec_value ? spec.spec_value.toLowerCase().includes(filter.spec_value.toLowerCase()) : false; break; } if (matches) { matchingRideIds.add(spec.ride_id); } }); filteredResults = filteredResults.filter((ride) => matchingRideIds.has(ride.id)); } } // Apply coaster statistics filters if (options.coasterStatFilters && options.coasterStatFilters.length > 0) { for (const filter of options.coasterStatFilters) { if (!filter.stat_name) continue; let statsQuery = supabase .from('ride_coaster_statistics') .select('ride_id, stat_name, stat_value') .eq('stat_name', filter.stat_name); if (filter.min_value !== undefined) { statsQuery = statsQuery.gte('stat_value', filter.min_value); } if (filter.max_value !== undefined) { statsQuery = statsQuery.lte('stat_value', filter.max_value); } const { data: statsData, error: statsError } = await statsQuery; if (statsError) throw statsError; const matchingRideIds = new Set(statsData?.map((stat) => stat.ride_id) || []); filteredResults = filteredResults.filter((ride) => matchingRideIds.has(ride.id)); } } setResults(filteredResults); } catch (err) { handleError(err, { action: 'Advanced Ride Search', metadata: { query: options.query, category: options.category, manufacturer: options.manufacturer } }); setError(err instanceof Error ? err.message : 'Search failed'); setResults([]); } finally { setLoading(false); } }; performSearch(); }, [ debouncedQuery, options.category, options.manufacturer, options.speedMin, options.speedMax, options.heightMin, options.heightMax, options.limit, JSON.stringify(options.technicalSpecFilters), JSON.stringify(options.coasterStatFilters), ]); return { results, loading, error }; }