import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'dart:ui'; // For BackdropFilter import 'navigation_controller.dart'; // ملاحظة: افترضتُ أن لديك لوناً أساسياً في هذا الملف // import 'package:sefer_driver/constant/colors.dart'; // سأستخدم اللون الأزرق كبديل مؤقت const Color kPrimaryColor = Color(0xFF0D47A1); class NavigationView extends StatelessWidget { const NavigationView({super.key}); @override Widget build(BuildContext context) { // استخدام Get.find() بدلاً من Get.put() لضمان أن الكونترولر مُهيأ مسبقاً // إذا كانت هذه هي نقطة الدخول، Get.put() صحيح. final NavigationController controller = Get.put(NavigationController()); return Scaffold( body: GetBuilder( builder: (_) => Stack( children: [ // --- الخريطة --- GoogleMap( onMapCreated: controller.onMapCreated, onLongPress: controller.onMapLongPressed, initialCameraPosition: CameraPosition( target: controller.myLocation ?? const LatLng(33.5138, 36.2765), // Default to Damascus zoom: 16.0, ), markers: controller.markers, polylines: controller.polylines, myLocationEnabled: false, myLocationButtonEnabled: false, compassEnabled: false, zoomControlsEnabled: false, buildingsEnabled: false, // تعديل الـ padding لإعطاء مساحة للعناصر العلوية والسفلية // مساحة أكبر في الأعلى للبحث + النتائج، ومساحة أكبر بالأسفل للملاحة padding: EdgeInsets.only( bottom: controller.currentInstruction.isNotEmpty ? 170 : 0, top: 150, ), ), // --- واجهة البحث (تصميم زجاجي) --- _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, ), ), ), ], ), ), ); } /// --- 1. واجهة البحث بالتصميم الزجاجي المطور --- 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: InputDecoration( hintText: 'إلى أين تريد الذهاب؟', hintStyle: const TextStyle( color: Colors.black45, fontSize: 16), border: InputBorder.none, contentPadding: const EdgeInsets.only(bottom: 2), ), ), ), // زر المسح أو إلغاء المسار if (controller .placeDestinationController.text.isNotEmpty) _buildClearButton(controller) else if (controller.polylines.isNotEmpty) _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, ), ), ], ), ), ), ); }, ), ), ), ); } /// --- 2. أزرار التحكم بالتصميم العائم --- Widget _buildFloatingMapControls(NavigationController controller) { return Positioned( // اجعلها تطفو فوق لوحة الملاحة bottom: controller.currentInstruction.isNotEmpty ? 190 : 24, right: 16, child: Column( children: [ if (controller.polylines.isNotEmpty) ...[ 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), ), ], ), ); } /// --- 3. واجهة الملاحة بالتصميم العائم المطور --- 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, ), ), ], ), ], ), ], ), ), ), ); } }