import React, { useState, useEffect } from 'react'; import { View, FlatList, StyleSheet, Text, TouchableOpacity, useWindowDimensions } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useNavigation, useRouter } from 'expo-router'; import { SearchBar } from '../../components/SearchBar'; import { MedicineCard } from '../../components/MedicineCard'; import { LoadingSpinner } from '../../components/LoadingSpinner'; import { useDebounce } from '../../hooks/useDebounce'; import { useAuth } from '../../hooks/useAuth'; import { useRecentSearches } from '../../hooks/useRecentSearches'; import { searchMedicines } from '../../services/medicines'; import { searchProducts, Product } from '../../services/products'; import { useThemeContext } from '../../components/ThemeProvider'; import { spacing, borderRadius } from '../../constants/theme'; import { Medicine } from '../../types'; import { config } from '../../constants/config'; const TABLET_MIN_WIDTH = 768; const suggestions = [ { name: 'Paracetamol', icon: 'medical' as const }, { name: 'Ibuprofeno', icon: 'fitness' as const }, { name: 'Aspirina', icon: 'heart' as const }, { name: 'Omeprazol', icon: 'bandage' as const }, ]; export default function SearchScreen() { const { width } = useWindowDimensions(); const isTablet = width >= TABLET_MIN_WIDTH; const { isAuthenticated } = useAuth(); const { recentSearches, addSearch, removeSearch } = useRecentSearches(); const { colors } = useThemeContext(); const [query, setQuery] = useState(''); const [results, setResults] = useState([]); const [products, setProducts] = useState([]); const [searchMode, setSearchMode] = useState<'all' | 'medicines' | 'products'>('all'); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const debouncedQuery = useDebounce(query, config.SEARCH_DEBOUNCE_MS); const navigation = useNavigation(); const router = useRouter(); useEffect(() => { const parent = navigation.getParent(); if (!parent) return; const unsubscribe = parent.addListener('tabPress', () => { setQuery(''); setResults([]); setProducts([]); setSearchMode('all'); setIsLoading(false); setError(null); }); return unsubscribe; }, [navigation]); useEffect(() => { if (debouncedQuery.length < 2) { setResults([]); setProducts([]); return; } const fetchResults = async () => { setIsLoading(true); setError(null); try { const data = await searchMedicines(debouncedQuery); setResults(data); } catch (err) { setError('Error al buscar medicamentos'); console.error(err); } finally { setIsLoading(false); } }; const fetchProducts = async () => { try { const productResults = await searchProducts(debouncedQuery); setProducts(productResults); } catch (err) { console.error('Product search error:', err); } }; fetchResults(); fetchProducts(); }, [debouncedQuery]); const handleSearch = (searchQuery: string) => { setQuery(searchQuery); if (searchQuery.trim()) addSearch(searchQuery); }; const showSuggestions = !query && !isLoading && results.length === 0 && products.length === 0; return ( {query.length >= 2 && ( setSearchMode('all')}> Todos setSearchMode('medicines')}> Medicamentos setSearchMode('products')}> Parafarmacia )} {showSuggestions && ( <> Sugerencias {suggestions.map((s) => ( handleSearch(s.name)} activeOpacity={0.7} > {s.name} ))} {isAuthenticated && recentSearches.length > 0 && ( Búsquedas recientes {recentSearches.map((term) => ( handleSearch(term)} activeOpacity={0.7} > {term} removeSearch(term)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}> ))} )} )} {isLoading && } {error && ( {error} )} {!isLoading && !error && results.length === 0 && products.length === 0 && query.length >= 2 && ( No se encontraron resultados )} item.nregistro} renderItem={({ item }) => } ListHeaderComponent={ <> {(searchMode === 'all' || searchMode === 'products') && products.length > 0 && ( Parafarmacia y Bebé {products.map((product) => ( router.push(`/product/${product.source}/${product.id}`)} activeOpacity={0.7} > {product.source === 'cima' ? 'CIMA' : 'OFF'} {product.name} {product.brand} ))} )} } contentContainerStyle={[styles.list, isTablet && styles.listTablet]} showsVerticalScrollIndicator={false} /> ); } const styles = StyleSheet.create({ container: { flex: 1, }, filterContainer: { flexDirection: 'row', justifyContent: 'center', gap: spacing.sm, paddingVertical: spacing.sm, paddingHorizontal: spacing.md, }, filterTab: { paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderRadius: borderRadius.full, backgroundColor: 'rgba(0,0,0,0.05)', }, filterTabActive: { backgroundColor: '#7fbf8f', }, filterText: { fontSize: 14, fontWeight: '600', color: '#41493e', }, filterTextActive: { color: '#ffffff', }, section: { paddingHorizontal: spacing.lg, marginTop: spacing.md, }, suggestionsSection: { marginTop: spacing.sm, alignSelf: 'center', width: '80%', }, suggestionsSectionTablet: { maxWidth: 700, alignSelf: 'center', width: '100%', }, sectionTitle: { fontSize: 20, fontWeight: '700', marginBottom: spacing.md, }, suggestionsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: spacing.sm, }, suggestionCard: { width: '48%' as unknown as number, borderRadius: borderRadius.lg, borderWidth: 1, padding: spacing.md, gap: spacing.sm, }, suggestionIcon: { width: 40, height: 40, borderRadius: borderRadius.md, alignItems: 'center', justifyContent: 'center', }, suggestionName: { fontSize: 16, fontWeight: '700', }, recentSection: { marginTop: spacing.lg, alignSelf: 'center', width: '80%', }, recentSectionTablet: { maxWidth: 700, alignSelf: 'center', width: '100%', }, recentItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: spacing.sm, gap: spacing.sm, }, recentText: { flex: 1, fontSize: 15, }, list: { paddingBottom: spacing.xl, }, listTablet: { maxWidth: 700, alignSelf: 'center', width: '100%', }, errorContainer: { padding: spacing.md, marginHorizontal: spacing.lg, borderRadius: borderRadius.lg, }, errorContainerTablet: { maxWidth: 700, alignSelf: 'center', }, errorText: { textAlign: 'center', fontSize: 14, }, emptyContainer: { padding: spacing.xl, alignItems: 'center', }, emptyText: { fontSize: 16, }, productCard: { flexDirection: 'row', alignItems: 'center', borderRadius: borderRadius.lg, borderWidth: 1, padding: spacing.md, marginBottom: spacing.sm, }, productInfo: { flex: 1, gap: 4, }, badges: { flexDirection: 'row', gap: spacing.sm, marginBottom: 2, }, sourceBadge: { paddingHorizontal: spacing.sm, paddingVertical: 2, borderRadius: borderRadius.sm, }, badgeText: { color: '#ffffff', fontSize: 11, fontWeight: '700', }, productName: { fontSize: 15, fontWeight: '600', }, productBrand: { fontSize: 13, }, });