import 'package:flutter/material.dart'; import '../services/app_state_service.dart'; class RouteSelectionBottomSheet extends StatefulWidget { final String title; final VoidCallback? onRouteChanged; const RouteSelectionBottomSheet({ super.key, this.title = 'Seleccionar Ruta', this.onRouteChanged, }); @override State createState() => _RouteSelectionBottomSheetState(); } class _RouteSelectionBottomSheetState extends State { final AppStateService _appStateService = AppStateService(); bool _isRefreshing = false; @override void initState() { super.initState(); _appStateService.addListener(_onStateChanged); } @override void dispose() { _appStateService.removeListener(_onStateChanged); super.dispose(); } void _onStateChanged() { if (mounted) { setState(() {}); } } Future _onRouteSelected(String routeId) async { try { await _appStateService.selectRoute(routeId); // Notify parent widget that route changed widget.onRouteChanged?.call(); if (mounted) { Navigator.pop(context); // Show success message ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Ruta cambiada: ${_appStateService.selectedRouteName}'), backgroundColor: Colors.green, duration: const Duration(seconds: 2), ), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error seleccionando ruta: $e'), backgroundColor: Colors.red, duration: const Duration(seconds: 3), ), ); } } } Future _refreshRoutes() async { setState(() { _isRefreshing = true; }); try { await _appStateService.refreshRoutes(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Rutas actualizadas'), backgroundColor: Colors.green, duration: Duration(seconds: 2), ), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error actualizando rutas: $e'), backgroundColor: Colors.red, duration: const Duration(seconds: 3), ), ); } } finally { if (mounted) { setState(() { _isRefreshing = false; }); } } } @override Widget build(BuildContext context) { final routes = _appStateService.allRoutes; final selectedRouteId = _appStateService.selectedRouteId; final isLoading = _appStateService.isLoadingRoutes || _isRefreshing; final error = _appStateService.error; return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), child: SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ // Handle Container( width: 40, height: 4, margin: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(2), ), ), // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( children: [ Expanded( child: Text( widget.title, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Color(0xFF101820), ), ), ), IconButton( onPressed: _refreshRoutes, icon: Icon( Icons.refresh, color: isLoading ? Colors.grey : const Color(0xFF101820), ), ), ], ), ), const SizedBox(height: 16), // Content Flexible( child: isLoading ? const Center( child: Padding( padding: EdgeInsets.all(40), child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Color(0xFFFEE715)), ), ), ) : error != null ? Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.error_outline, color: Colors.red[600], size: 48, ), const SizedBox(height: 16), Text( error, textAlign: TextAlign.center, style: TextStyle( color: Colors.red[600], fontSize: 16, ), ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: _refreshRoutes, icon: const Icon(Icons.refresh), label: const Text('Reintentar'), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFFEE715), foregroundColor: const Color(0xFF101820), ), ), ], ), ) : routes.isEmpty ? const Padding( padding: EdgeInsets.all(40), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.route_outlined, color: Colors.grey, size: 48, ), SizedBox(height: 16), Text( 'No hay rutas disponibles', style: TextStyle( fontSize: 16, color: Colors.grey, ), ), ], ), ) : ListView.builder( shrinkWrap: true, itemCount: routes.length, itemBuilder: (context, index) { final route = routes[index]; final isSelected = selectedRouteId == route.id; return ListTile( leading: Container( width: 12, height: 12, decoration: BoxDecoration( color: Color(int.parse(route.color .replaceFirst('#', '0xFF'))), shape: BoxShape.circle, ), ), title: Text( route.displayName, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), subtitle: route.direction.isNotEmpty ? Text( route.direction, style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ) : null, trailing: isSelected ? const Icon( Icons.check_circle, color: Color(0xFFFEE715), ) : null, onTap: () => _onRouteSelected(route.id), ); }, ), ), const SizedBox(height: 16), ], ), ), ); } }