import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:provider/provider.dart'; import '../estado/estado_radio.dart'; import '../widgets/tarjeta_emisora.dart'; const _paises = [ ('España', 'ES'), ('USA', 'US'), ('México', 'MX'), ('Argentina', 'AR'), ('UK', 'GB'), ('Francia', 'FR'), ('Alemania', 'DE'), ('Italia', 'IT'), ('Brasil', 'BR'), ('Japón', 'JP'), ]; const _idiomas = [ 'spanish', 'english', 'french', 'german', 'portuguese', 'italian', 'japanese', 'arabic', 'russian', ]; /// Pantalla de búsqueda avanzada de emisoras. class PantallaBuscar extends StatefulWidget { const PantallaBuscar({super.key}); @override State createState() => _PantallaBuscarState(); } class _PantallaBuscarState extends State { final _controller = TextEditingController(); String? _paisSeleccionado; String? _idiomaSeleccionado; bool _buscando = false; @override void dispose() { _controller.dispose(); super.dispose(); } void _buscar() { final q = _controller.text.trim(); context.read().buscar( nombre: q.isNotEmpty ? q : null, pais: _paisSeleccionado, idioma: _idiomaSeleccionado, ); } @override Widget build(BuildContext context) { final estado = context.watch(); final theme = Theme.of(context); return Column( children: [ // Barra de búsqueda Padding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 0), child: SearchBar( controller: _controller, hintText: 'Nombre de la emisora...', leading: const Icon(Icons.search), trailing: [ if (_controller.text.isNotEmpty) IconButton( icon: const Icon(Icons.clear), onPressed: () { _controller.clear(); setState(() {}); }, ), ], onSubmitted: (_) => _buscar(), onChanged: (_) => setState(() {}), ), ), // Filtros país _seccionFiltro( theme, 'País', _paises.map((p) => (p.$1, p.$2)).toList(), _paisSeleccionado, (v) => setState(() { _paisSeleccionado = v; _buscar(); }), ), // Filtros idioma _seccionFiltro( theme, 'Idioma', _idiomas.map((i) => (i, i)).toList(), _idiomaSeleccionado, (v) => setState(() { _idiomaSeleccionado = v; _buscar(); }), ), // Resultados Expanded( child: _resultados(estado, theme), ), ], ); } Widget _seccionFiltro( ThemeData theme, String titulo, List<(String, String)> opciones, String? seleccionado, void Function(String?) onChanged, ) { return Padding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(titulo, style: theme.textTheme.labelLarge), const SizedBox(height: 4), SizedBox( height: 36, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: opciones.length, separatorBuilder: (_, __) => const SizedBox(width: 6), itemBuilder: (_, i) { final (label, value) = opciones[i]; final sel = seleccionado == value; return FilterChip( label: Text(label), selected: sel, visualDensity: VisualDensity.compact, onSelected: (_) => onChanged(sel ? null : value), ); }, ), ), ], ), ); } Widget _resultados(EstadoRadio estado, ThemeData theme) { if (estado.cargandoBusqueda) { return const Center(child: CircularProgressIndicator()); } final resultados = estado.resultadosBusqueda; if (resultados.isEmpty) { final sinFiltros = _controller.text.isEmpty && _paisSeleccionado == null && _idiomaSeleccionado == null; return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.search, size: 64, color: theme.colorScheme.outlineVariant), const SizedBox(height: 16), Text( sinFiltros ? 'Busca una emisora' : 'Sin resultados', style: theme.textTheme.titleMedium, ), ], ), ); } return ListView.separated( padding: const EdgeInsets.all(16), itemCount: resultados.length, separatorBuilder: (_, __) => const SizedBox(height: 4), itemBuilder: (context, i) => TarjetaEmisora( emisora: resultados[i], esCompacta: true, onTap: () => context.read().reproducir(resultados[i]), ).animate().fadeIn(delay: (i * 20).ms), ); } }