import 'package:flutter/material.dart'; import 'camion_estado.dart'; // ─── DATOS DE COLONIAS (de tu colonias-rutas.json) ────────────── const List> _coloniasRutas = [ {'colonia': 'Zona Centro', 'routeId': 'RUTA-01', 'horario': 'Matutino (06:30 - 07:15)'}, {'colonia': 'Las Arboledas', 'routeId': 'RUTA-01', 'horario': 'Matutino (07:00 - 07:30)'}, {'colonia': 'Trojes', 'routeId': 'RUTA-13', 'horario': 'Matutino (06:40 - 07:10)'}, {'colonia': 'San Juanico', 'routeId': 'RUTA-03', 'horario': 'Matutino (06:45 - 07:15)'}, {'colonia': 'Los Olivos', 'routeId': 'RUTA-04', 'horario': 'Matutino (07:00 - 07:40)'}, {'colonia': 'Rancho Seco', 'routeId': 'RUTA-05', 'horario': 'Vespertino (14:15 - 15:00)'}, {'colonia': 'Las Insurgentes', 'routeId': 'RUTA-12', 'horario': 'Matutino (06:35 - 07:10)'}, ]; // ════════════════════════════════════════════════════════════════ // PANTALLA RUTA EXCLUSIVA // ════════════════════════════════════════════════════════════════ class RutaExclusivaScreen extends StatefulWidget { final String direccionUsuario; // ← viene desde domicilios.dart final String coloniaUsuario; // ← viene desde domicilios.dart const RutaExclusivaScreen({ super.key, required this.direccionUsuario, required this.coloniaUsuario, }); @override State createState() => _RutaExclusivaScreenState(); } class _RutaExclusivaScreenState extends State { Map? _rutaAsignada; // solo la ruta del usuario bool _accesoValidado = false; bool _cargando = true; @override void initState() { super.initState(); camionEstado.addListener(_actualizar); _validarAcceso(); } void _actualizar() { if (mounted) setState(() {}); } @override void dispose() { camionEstado.removeListener(_actualizar); super.dispose(); } // ── Valida que la colonia del usuario exista en las rutas ──── void _validarAcceso() async { await Future.delayed(const Duration(milliseconds: 800)); // simula carga final coloniaLower = widget.coloniaUsuario.trim().toLowerCase(); final encontrada = _coloniasRutas.firstWhere( (r) => r['colonia']!.toLowerCase() == coloniaLower, orElse: () => {}, ); setState(() { _cargando = false; if (encontrada.isNotEmpty) { _rutaAsignada = encontrada; _accesoValidado = true; } else { _accesoValidado = false; } }); } // ── Color según etapa del camión ───────────────────────────── Color _colorEtapa() { final id = camionEstado.positionId; if (id <= 1) return Colors.grey; if (id <= 3) return Colors.blue; if (id <= 5) return Colors.orange; if (id == 6) return Colors.green; return Colors.grey; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[100], appBar: AppBar( title: const Text('Mi Ruta Asignada'), backgroundColor: Colors.green, foregroundColor: Colors.white, ), body: _cargando ? _buildCargando() : _accesoValidado ? _buildRutaValidada() : _buildSinAcceso(), ); } // ── Pantalla de carga ──────────────────────────────────────── Widget _buildCargando() { return const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(color: Colors.green), SizedBox(height: 16), Text( 'Validando tu dirección...', style: TextStyle(color: Colors.grey, fontSize: 14), ), ], ), ); } // ── Sin acceso: colonia no registrada ──────────────────────── Widget _buildSinAcceso() { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.lock_outline, size: 80, color: Colors.red[300]), const SizedBox(height: 20), const Text( 'Dirección no reconocida', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Text( 'Tu colonia "${widget.coloniaUsuario}" no está registrada en el sistema de rutas. Actualiza tu domicilio o contacta al municipio.', textAlign: TextAlign.center, style: TextStyle(fontSize: 14, color: Colors.grey[600]), ), const SizedBox(height: 28), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () => Navigator.pop(context), icon: const Icon(Icons.arrow_back), label: const Text('Actualizar domicilio'), ), ], ), ), ); } // ── Ruta validada: solo info de SU ruta ────────────────────── Widget _buildRutaValidada() { final ruta = _rutaAsignada!; final etapa = CamionEstado.etapas[camionEstado.positionId] ?? ''; final etaInfo = CamionEstado.etaInfo[camionEstado.positionId]!; final color = _colorEtapa(); final minutos = etaInfo['minutos'] as int; return ListView( padding: const EdgeInsets.all(16), children: [ // ── BADGE DE ACCESO VALIDADO ────────────────────── Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), decoration: BoxDecoration( color: Colors.green[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.green), ), child: Row( children: [ const Icon(Icons.verified_user, color: Colors.green), const SizedBox(width: 10), Expanded( child: Text( 'Acceso validado para ${widget.coloniaUsuario}. Solo ves la información de tu ruta.', style: const TextStyle( fontSize: 13, color: Colors.green, fontWeight: FontWeight.w600, ), ), ), ], ), ), const SizedBox(height: 16), // ── CARD: DATOS DE LA RUTA ──────────────────────── Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.route, color: Colors.green, size: 28), const SizedBox(width: 10), Text( ruta['routeId']!, style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.green, ), ), ], ), const SizedBox(height: 16), _filaInfo(Icons.location_on, 'Colonia', ruta['colonia']!), _filaInfo(Icons.schedule, 'Horario', ruta['horario']!), _filaInfo(Icons.home, 'Dirección', widget.direccionUsuario), ], ), ), ), const SizedBox(height: 16), // ── CARD: ESTADO EN TIEMPO REAL ─────────────────── Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(Icons.local_shipping, color: Colors.green, size: 28), SizedBox(width: 10), Text( 'Estado en tiempo real', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 16), // Barra de progreso ClipRRect( borderRadius: BorderRadius.circular(8), child: LinearProgressIndicator( value: camionEstado.positionId / 8, minHeight: 12, backgroundColor: Colors.grey[200], valueColor: AlwaysStoppedAnimation(color), ), ), const SizedBox(height: 12), // Etapa actual Container( width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: color.withValues(alpha:0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: color.withValues(alpha:0.3)), ), child: Text( etapa, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: color, ), ), ), const SizedBox(height: 12), // ETA if (minutos > 0) Container( width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: Colors.green[50], borderRadius: BorderRadius.circular(12), ), child: Row( children: [ const Icon(Icons.timer, color: Colors.green), const SizedBox(width: 10), Text( 'Llega en aproximadamente $minutos minutos', style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.green, ), ), ], ), ), ], ), ), ), const SizedBox(height: 16), // ── AVISO PRIVACIDAD ────────────────────────────── Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.blue.shade200), ), child: const Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Icons.shield, color: Colors.blue), SizedBox(width: 10), Expanded( child: Text( 'Visión de túnel activa: No puedes ver rutas, horarios ni ubicaciones de otras colonias.', style: TextStyle(fontSize: 13, color: Colors.blue), ), ), ], ), ), ], ); } // ── Widget auxiliar para filas de info ─────────────────────── Widget _filaInfo(IconData icono, String label, String valor) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(icono, color: Colors.green, size: 20), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle(fontSize: 12, color: Colors.grey[500]), ), Text( valor, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, ), ), ], ), ], ), ); } }