import { useState, useEffect, useCallback } from 'react'; import { OpenRouterModel } from '../lib/openrouter'; interface UseOpenRouterModelsResult { models: OpenRouterModel[]; filteredModels: OpenRouterModel[]; loading: boolean; error: string | null; searchTerm: string; setSearchTerm: (term: string) => void; selectedCategory: string; setSelectedCategory: (category: string) => void; refetch: () => Promise; categories: string[]; } export function useOpenRouterModels(): UseOpenRouterModelsResult { const [models, setModels] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [searchTerm, setSearchTerm] = useState(''); const [selectedCategory, setSelectedCategory] = useState('all'); const fetchModels = useCallback(async () => { if (loading) return; // Prevent multiple simultaneous requests console.log('🔄 Fetching OpenRouter models...'); setLoading(true); setError(null); try { const url = new URL('/api/openrouter/models', window.location.origin); console.log('📡 Requesting:', url.toString()); const response = await fetch(url.toString()); console.log('📥 Response status:', response.status); const result = await response.json(); console.log('📋 Response data:', result); if (!result.success) { throw new Error(result.error || 'Failed to fetch models'); } console.log('✅ Successfully fetched', result.data.length, 'models'); setModels(result.data); } catch (err) { console.error('❌ Error fetching models:', err); setError(err instanceof Error ? err.message : 'Failed to fetch models'); } finally { setLoading(false); } }, []); // Remove loading dependency to prevent infinite loop useEffect(() => { fetchModels(); }, [fetchModels]); // Extract categories from model names/descriptions const categories = [ 'all', ...Array.from(new Set( models .map(model => { const provider = model.id.split('/')[0]; return provider; }) .filter(Boolean) )).sort() ]; // Filter models based on search term and category const filteredModels = models.filter(model => { const matchesSearch = !searchTerm || model.name.toLowerCase().includes(searchTerm.toLowerCase()) || model.id.toLowerCase().includes(searchTerm.toLowerCase()) || model.description.toLowerCase().includes(searchTerm.toLowerCase()); const matchesCategory = selectedCategory === 'all' || model.id.startsWith(selectedCategory + '/'); return matchesSearch && matchesCategory; }); return { models, filteredModels, loading, error, searchTerm, setSearchTerm, selectedCategory, setSelectedCategory, refetch: fetchModels, categories }; }