import 'package:Intaleq/constant/colors.dart'; import 'package:Intaleq/constant/links.dart'; import 'package:Intaleq/constant/style.dart'; import 'package:Intaleq/controller/home/map_passenger_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; // لتنسيق الأرقام import '../../../constant/box_name.dart'; import '../../../controller/firebase/notification_service.dart'; import '../../../controller/functions/launch.dart'; import '../../../main.dart'; import '../../widgets/my_textField.dart'; class ApplyOrderWidget extends StatelessWidget { const ApplyOrderWidget({super.key}); @override Widget build(BuildContext context) { // دالة لتحويل كود اللون الهيكس إلى لون Color parseColor(String colorHex) { if (colorHex.isEmpty) return Colors.grey; try { String processedHex = colorHex.replaceFirst('#', '').trim(); if (processedHex.length == 6) processedHex = 'FF$processedHex'; return Color(int.parse('0x$processedHex')); } catch (e) { return Colors.grey; } } return Obx(() { final controller = Get.find(); final bool isVisible = controller.currentRideState.value == RideState.driverApplied || controller.currentRideState.value == RideState.driverArrived; return AnimatedPositioned( duration: const Duration(milliseconds: 500), curve: Curves.elasticOut, // تأثير حركي أجمل bottom: isVisible ? 0 : -Get.height * 0.6, left: 0, right: 0, child: Container( // height: Get.height * 0.38, // زيادة الارتفاع قليلاً للتصميم الجديد decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), boxShadow: [ BoxShadow( blurRadius: 20, spreadRadius: 2, color: Colors.black.withOpacity(0.15), offset: const Offset(0, -2), ) ], ), padding: const EdgeInsets.fromLTRB(20, 10, 20, 20), child: GetBuilder( builder: (c) { return Column( mainAxisSize: MainAxisSize.min, children: [ // مقبض صغير في الأعلى Container( width: 40, height: 5, decoration: BoxDecoration( color: Colors.grey.withOpacity(0.3), borderRadius: BorderRadius.circular(10), ), ), const SizedBox(height: 15), // السعر والعنوان _buildPriceHeader(context, c), const SizedBox(height: 15), // كرت المعلومات الرئيسي (سائق + سيارة) _buildMainInfoCard(context, c, parseColor), const SizedBox(height: 15), // أزرار الاتصال _buildContactButtonsRow(context, c), const SizedBox(height: 15), // شريط الوقت c.currentRideState.value == RideState.driverArrived ? const DriverArrivePassengerAndWaitMinute() : const TimeDriverToPassenger(), ], ); }, ), ), ); }); } // --------------------------------------------------------------------------- // 1. قسم السعر (مع التنسيق الجديد) // --------------------------------------------------------------------------- Widget _buildPriceHeader( BuildContext context, MapPassengerController controller) { // تنسيق الرقم (مثلاً: 60,000) final formatter = NumberFormat("#,###"); String formattedPrice = formatter.format(controller.totalPassenger); return Column( children: [ Text( 'Driver Accepted Request'.tr, style: AppStyle.subtitle.copyWith(color: Colors.grey[600]), ), const SizedBox(height: 5), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( formattedPrice, style: AppStyle.title.copyWith( fontSize: 28, fontWeight: FontWeight.w900, color: AppColor.primaryColor, ), ), const SizedBox(width: 5), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'SYP'.tr, style: AppStyle.subtitle.copyWith( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey[700], ), ), ), ], ), ], ); } // --------------------------------------------------------------------------- // 2. كرت المعلومات الرئيسي (السائق + السيارة 3D) // --------------------------------------------------------------------------- Widget _buildMainInfoCard(BuildContext context, MapPassengerController controller, Color Function(String) parseColor) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).scaffoldBackgroundColor, // لون خلفية فاتح borderRadius: BorderRadius.circular(20), border: Border.all(color: Colors.grey.withOpacity(0.1)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // الجزء الأيسر: معلومات السائق Expanded( child: Row( children: [ // صورة السائق Container( padding: const EdgeInsets.all(3), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: AppColor.primaryColor, width: 2), ), child: CircleAvatar( radius: 26, backgroundImage: NetworkImage( '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'), onBackgroundImageError: (exception, stackTrace) => const Icon(Icons.person, size: 26, color: Colors.grey), ), ), const SizedBox(width: 12), // الاسم والتقييم والسيارة نص Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( controller.driverName, style: AppStyle.title.copyWith( fontSize: 16, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Row( children: [ const Icon(Icons.star, color: Colors.amber, size: 16), const SizedBox(width: 4), Text( controller.driverRate, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13), ), ], ), const SizedBox(height: 4), Text( '${controller.model} • ${controller.licensePlate}', style: TextStyle(color: Colors.grey[600], fontSize: 12), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ), // الجزء الأيمن: أيقونة السيارة الـ 3D _build3DCarIcon(controller, parseColor), ], ), ); } // --------------------------------------------------------------------------- // 3. أيقونة السيارة الـ 3D (الدائرة والظلال والخلفية الذكية) // --------------------------------------------------------------------------- Widget _build3DCarIcon( MapPassengerController controller, Color Function(String) parseColor) { Color carColor = parseColor(controller.colorHex); // تحديد سطوع لون السيارة لتحديد لون الخلفية // إذا كانت السيارة فاتحة (أكثر من 0.6)، الخلفية تكون غامقة، والعكس bool isCarLight = carColor.computeLuminance() > 0.6; // ألوان الخلفية للدائرة Color bgGradientStart = isCarLight ? Colors.blueGrey.shade700 : Colors.grey.shade100; Color bgGradientEnd = isCarLight ? Colors.blueGrey.shade900 : Colors.grey.shade300; Color borderColor = isCarLight ? Colors.blueGrey.shade600 : Colors.white; return Container( width: 75, height: 75, padding: const EdgeInsets.all(12), decoration: BoxDecoration( shape: BoxShape.circle, // تدرج لوني للخلفية لتبدو 3D gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [bgGradientStart, bgGradientEnd], ), border: Border.all(color: borderColor, width: 2), // ظلال لرفع الدائرة عن السطح boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 10, offset: const Offset(4, 4), ), BoxShadow( color: Colors.white.withOpacity(isCarLight ? 0.1 : 0.8), blurRadius: 10, offset: const Offset(-4, -4), ), ], ), child: Center( child: ColorFiltered( colorFilter: ColorFilter.mode(carColor, BlendMode.srcIn), child: Image.asset( box.read(BoxName.carType) == 'Scooter' || box.read(BoxName.carType) == 'Pink Bike' ? 'assets/images/moto.png' : 'assets/images/car3.png', fit: BoxFit.contain, ), ), ), ); } // --------------------------------------------------------------------------- // 4. أزرار الاتصال (بتصميم جديد) // --------------------------------------------------------------------------- Widget _buildContactButtonsRow( BuildContext context, MapPassengerController controller) { return Row( children: [ Expanded( child: _buildActionButton( label: 'Message'.tr, icon: Icons.chat_bubble_outline_rounded, color: AppColor.blueColor, onTap: () => _showContactOptionsDialog(context, controller), ), ), const SizedBox(width: 15), Expanded( child: _buildActionButton( label: 'Call'.tr, icon: Icons.phone_rounded, color: AppColor.greenColor, onTap: () { HapticFeedback.heavyImpact(); makePhoneCall(controller.driverPhone); }, ), ), ], ); } Widget _buildActionButton({ required String label, required IconData icon, required Color color, required VoidCallback onTap, }) { return ElevatedButton( onPressed: onTap, style: ElevatedButton.styleFrom( backgroundColor: color.withOpacity(0.1), foregroundColor: color, elevation: 0, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: 20), const SizedBox(width: 8), Text( label, style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), ); } // --- النوافذ المنبثقة للرسائل (نفس المنطق القديم) --- void _showContactOptionsDialog( BuildContext context, MapPassengerController controller) { Get.bottomSheet( Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Quick Message'.tr, style: AppStyle.title), const SizedBox(height: 15), ..._buildPredefinedMessages(controller), const Divider(height: 30), _buildCustomMessageInput(controller, context), SizedBox( height: MediaQuery.of(context).viewInsets.bottom), // للكيبورد ], ), ), isScrollControlled: true, ); } List _buildPredefinedMessages(MapPassengerController controller) { const messages = [ 'Hello, I\'m at the agreed-upon location', 'I\'m waiting for you', "How much longer will you be?", ]; return messages .map((message) => Padding( padding: const EdgeInsets.only(bottom: 10.0), child: InkWell( onTap: () { _sendMessage(controller, message.tr); Get.back(); }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 15), decoration: BoxDecoration( color: Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Row( children: [ const Icon(Icons.quickreply_rounded, size: 18, color: Colors.grey), const SizedBox(width: 10), Expanded( child: Text(message.tr, style: AppStyle.subtitle)), ], ), ), ), )) .toList(); } Widget _buildCustomMessageInput( MapPassengerController controller, BuildContext context) { return Row( children: [ Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 15), decoration: BoxDecoration( color: Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(25), ), child: Form( key: controller.messagesFormKey, child: TextFormField( controller: controller.messageToDriver, decoration: InputDecoration( hintText: 'Type your message...'.tr, border: InputBorder.none, ), ), ), ), ), const SizedBox(width: 10), CircleAvatar( backgroundColor: AppColor.primaryColor, child: IconButton( onPressed: () { if (controller.messagesFormKey.currentState!.validate()) { _sendMessage(controller, controller.messageToDriver.text); controller.messageToDriver.clear(); Get.back(); } }, icon: const Icon(Icons.send_rounded, color: Colors.white, size: 20), ), ), ], ); } void _sendMessage(MapPassengerController controller, String text) { NotificationService.sendNotification( category: 'message From passenger', target: controller.driverToken.toString(), title: 'Message From passenger'.tr, body: text, isTopic: false, tone: 'ding', driverList: [], ); } } // ----------------------------------------------------------------------------- // مؤشرات الانتظار والوقت (نفس المنطق مع تحسين بسيط في التصميم) // ----------------------------------------------------------------------------- class DriverArrivePassengerAndWaitMinute extends StatelessWidget { const DriverArrivePassengerAndWaitMinute({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Driver is waiting'.tr, style: const TextStyle(fontWeight: FontWeight.bold)), Text( controller.stringRemainingTimeDriverWaitPassenger5Minute, style: const TextStyle( fontWeight: FontWeight.bold, color: AppColor.redColor), ), ], ), const SizedBox(height: 6), ClipRRect( borderRadius: BorderRadius.circular(10), child: LinearProgressIndicator( backgroundColor: Colors.grey[200], color: controller.remainingTimeDriverWaitPassenger5Minute < 60 ? AppColor.redColor : AppColor.greenColor, minHeight: 8, value: controller.progressTimerDriverWaitPassenger5Minute.toDouble(), ), ), ], ); }); } } class TimeDriverToPassenger extends StatelessWidget { const TimeDriverToPassenger({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { if (controller.timeToPassengerFromDriverAfterApplied <= 0) { return const SizedBox(); } return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Driver arriving in'.tr, style: const TextStyle(fontWeight: FontWeight.bold)), Text( controller.stringRemainingTimeToPassenger, style: const TextStyle( fontWeight: FontWeight.bold, color: AppColor.primaryColor), ), ], ), const SizedBox(height: 6), ClipRRect( borderRadius: BorderRadius.circular(10), child: LinearProgressIndicator( backgroundColor: Colors.grey[200], color: AppColor.primaryColor, minHeight: 8, value: controller.progressTimerToPassengerFromDriverAfterApplied .toDouble() .clamp(0.0, 1.0), ), ), ], ); }); } }