import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; // Replaced Google Maps import 'dart:ui'; import 'navigation_controller.dart'; const Color kPrimaryColor = Color(0xFF0D47A1); class NavigationView extends StatelessWidget { const NavigationView({super.key}); @override Widget build(BuildContext context) { final NavigationController controller = Get.put(NavigationController()); return Scaffold( body: GetBuilder( builder: (_) => Stack( children: [ // --- الخريطة --- MapLibreMap( onMapCreated: controller.onMapCreated, onStyleLoadedCallback: controller.onStyleLoaded, onMapLongClick: controller.onMapLongPressed, styleString: "assets/style.json", initialCameraPosition: CameraPosition( target: controller.myLocation ?? const LatLng(33.5138, 36.2765), zoom: 16.0, ), myLocationEnabled: false, compassEnabled: false, ), // --- واجهة البحث (تصميم زجاجي) --- _buildGlassSearchUI(controller), // --- إرشادات الملاحة (تصميم عائم) --- if (controller.currentInstruction.isNotEmpty) _buildFloatingNavigationUI(controller), // --- أزرار التحكم (تصميم عائم) --- _buildFloatingMapControls(controller), // --- مؤشر التحميل --- if (controller.isLoading) Container( color: Colors.black.withOpacity(0.5), child: const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.white), strokeWidth: 3, ), ), ), ], ), ), ); } // --- All UI Sub-Widgets remain identical, simply change the 'if' checks to rely on the new variables --- Widget _buildGlassSearchUI(NavigationController controller) { return Positioned( top: 0, left: 0, right: 0, child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), child: Column( children: [ ClipRRect( borderRadius: BorderRadius.circular(28.0), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( height: 56, decoration: BoxDecoration( color: Colors.white.withOpacity(0.85), borderRadius: BorderRadius.circular(28.0), border: Border.all(color: Colors.white.withOpacity(0.4)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 15, offset: const Offset(0, 5)), ], ), child: Row( children: [ const Padding( padding: EdgeInsets.only(left: 18.0, right: 10.0), child: Icon(Icons.search, color: kPrimaryColor, size: 24), ), Expanded( child: TextField( controller: controller.placeDestinationController, onChanged: controller.onSearchChanged, textInputAction: TextInputAction.search, style: const TextStyle( fontSize: 16, color: Colors.black87), decoration: const InputDecoration( hintText: 'إلى أين تريد الذهاب؟', hintStyle: TextStyle( color: Colors.black45, fontSize: 16), border: InputBorder.none, contentPadding: EdgeInsets.only(bottom: 2), ), ), ), if (controller .placeDestinationController.text.isNotEmpty) _buildClearButton(controller) else if (controller.destinationSymbol != null) // Changed condition here _buildCancelRouteButton(controller), ], ), ), ), ), const SizedBox(height: 10), if (controller.placesDestination.isNotEmpty) _buildSearchResultsList(controller), ], ), ), ), ); } Widget _buildClearButton(NavigationController controller) { return IconButton( icon: const Icon(Icons.clear, color: Colors.grey, size: 22), onPressed: () { controller.placeDestinationController.clear(); controller.placesDestination = []; controller.update(); }, ); } Widget _buildCancelRouteButton(NavigationController controller) { return IconButton( tooltip: 'إلغاء المسار', icon: const Icon(Icons.close, color: Colors.redAccent, size: 22), onPressed: () => controller.clearRoute(), ); } Widget _buildSearchResultsList(NavigationController controller) { return ClipRRect( borderRadius: BorderRadius.circular(24.0), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( constraints: const BoxConstraints(maxHeight: 220), decoration: BoxDecoration( color: Colors.white.withOpacity(0.85), borderRadius: BorderRadius.circular(24.0), border: Border.all(color: Colors.white.withOpacity(0.4)), ), child: ListView.builder( padding: const EdgeInsets.symmetric(vertical: 8.0), itemCount: controller.placesDestination.length, itemBuilder: (context, index) { final place = controller.placesDestination[index]; final distance = place['distanceKm'] as double?; final address = (place['address'] ?? '').toString(); return Material( color: Colors.transparent, child: InkWell( onTap: () => controller.selectDestination(place), child: Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, vertical: 12.0), child: Row( children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: kPrimaryColor.withOpacity(0.1), shape: BoxShape.circle), child: const Icon(Icons.location_on_outlined, color: kPrimaryColor, size: 20), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(place['name'] ?? 'اسم غير معروف', style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 16, color: Colors.black87), maxLines: 1, overflow: TextOverflow.ellipsis), if (address.isNotEmpty) Text(address, style: const TextStyle( color: Colors.black54, fontSize: 13), maxLines: 1, overflow: TextOverflow.ellipsis), ], ), ), const SizedBox(width: 10), if (distance != null) Text('${distance.toStringAsFixed(1)} كم', style: const TextStyle( color: kPrimaryColor, fontWeight: FontWeight.w500, fontSize: 13)), ], ), ), ), ); }, ), ), ), ); } Widget _buildFloatingMapControls(NavigationController controller) { return Positioned( bottom: controller.currentInstruction.isNotEmpty ? 190 : 24, right: 16, child: Column( children: [ if (controller.destinationSymbol != null) ...[ // Changed condition FloatingActionButton( heroTag: 'rerouteBtn', backgroundColor: Colors.white, elevation: 6, onPressed: () => controller.recalculateRoute(), tooltip: 'إعادة حساب المسار', child: const Icon(Icons.sync_alt, color: kPrimaryColor, size: 24), ), const SizedBox(height: 12), ], FloatingActionButton( heroTag: 'gpsBtn', backgroundColor: Colors.white, elevation: 6, onPressed: () { if (controller.myLocation != null) { controller.animateCameraToPosition(controller.myLocation!, bearing: controller.heading, zoom: 18.5); } }, child: const Icon(Icons.gps_fixed, color: Colors.black54, size: 24), ), ], ), ); } Widget _buildFloatingNavigationUI(NavigationController controller) { return Positioned( bottom: 16, left: 16, right: 16, child: Container( decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF1E88E5), Color(0xFF0D47A1)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), borderRadius: BorderRadius.circular(28), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.3), blurRadius: 25, offset: const Offset(0, 10)) ], ), child: Padding( padding: const EdgeInsets.fromLTRB(22, 20, 22, 22), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), shape: BoxShape.circle), child: const Icon(Icons.navigation_rounded, color: Colors.white, size: 28), ), const SizedBox(width: 16), Expanded( child: Text( controller.currentInstruction, style: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, height: 1.3), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), const SizedBox(width: 16), Text(controller.distanceToNextStep, style: const TextStyle( color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold)), ], ), if (controller.nextInstruction.isNotEmpty || controller.currentSpeed > 0) const Padding( padding: EdgeInsets.symmetric(vertical: 14.0), child: Divider(color: Colors.white30, height: 1), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: controller.nextInstruction.isNotEmpty ? Text( 'التالي: ${controller.nextInstruction}', style: const TextStyle( color: Colors.white70, fontSize: 15, fontWeight: FontWeight.w500), maxLines: 1, overflow: TextOverflow.ellipsis, ) : const SizedBox(), ), Row( children: [ Text(controller.currentSpeed.toStringAsFixed(0), style: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold)), const SizedBox(width: 6), const Text('كم/س', style: TextStyle( color: Colors.white70, fontSize: 14, fontWeight: FontWeight.w500)), ], ), ], ), ], ), ), ), ); } }