# 🚗 دورة حياة الرحلة - تطبيق السائق (Driver Ride Lifecycle)

<div dir="rtl" align="right">
هذا الملف هو مرجع هندسي شامل ودقيق (Source of Truth) يوضح كافة تفاصيل دورة حياة الرحلة (Ride Lifecycle) في تطبيق السائق (Siro Driver). تمت كتابته وتوثيقه ليكون دليلاً استرشادياً كاملاً لأي مهندس برمجي أو نموذج ذكاء اصطناعي (AI Agent) يرغب في فهم أو تعديل منطق الرحلات، تتبع المواقع، أو معالجة الحالات الفعالة.
</div>

---

## 1. بنية مزود الموقع المركزي (LocationController)

<div dir="rtl" align="right">
يعد الكنترولر 
[LocationController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/functions/location_controller.dart)
هو المصدر الوحيد والمركزى (Single Source of Truth) لكافة تحديثات نظام التموضع العالمي (GPS). يُمنع منعاً باتاً إنشاء اشتراكات أو فتح قنوات استماع موازية مع Geolocator أو Location في أي مكان آخر.
</div>

### 1.1 التهيئة والتحكم في دورة الحياة (Initialization & Lifecycle)

<div dir="rtl" align="right">
* <b>دالة التهيئة</b>:
</div>

```dart
Future<void> onInit() async
```

<div dir="rtl" align="right">
تقوم بالخطوات التالية:
1. تسجيل الكنترولر كمراقب لدورة حياة التطبيق العامة عبر `WidgetsBinding.instance.addObserver(this)`.
2. الاستماع للمفتاح `BoxName.statusDriverLocation` للتحقق من حالة السائق (مثال: محظور `blocked`). إذا تم حظره، يتم إيقاف تتبع الموقع فوراً وتحديث السيرفر وفصل الاتصال.
3. انتظار تحميل الكنترولرات المعتمد عليها (`HomeCaptainController` و `CaptainWalletController`) عبر الدالة المساعدة `_awaitDependencies()`.
4. تهيئة الاتصال بالسوكيت عبر `initSocket()` وتهيئة إعدادات تحديد الموقع عبر `_initLocationSettings()` والبدء الفوري ببث الموقع في حال لم يكن السائق محظوراً.
</div>

<div dir="rtl" align="right">
* <b>مراقبة تغيير حالة التطبيق</b>:
</div>

```dart
void didChangeAppLifecycleState(AppLifecycleState state)
```

<div dir="rtl" align="right">
1. في حالة **Resumed** (التطبيق في الواجهة): يتم إيقاف تشغيل خدمة الخلفية للأندرويد عبر `BackgroundServiceHelper.stopService()`، وإعادة تهيئة السوكيت إذا تم قطعه.
2. في حالة **Paused** أو **Detached** (التطبيق في الخلفية): يتم حفظ الحالة محلياً وتشغيل خدمة الخلفية `BackgroundServiceHelper.startService()` لضمان استمرارية البث.
</div>

### 1.2 الاتصال بالويب سوكيت (WebSocket & Socket.io)

<div dir="rtl" align="right">
* <b>تهيئة السوكيت</b>:
</div>

```dart
void initSocket()
```

<div dir="rtl" align="right">
تقوم بفتح قناة اتصال مع خادم المواقع (`https://location.intaleq.xyz`) وتجهيز معلمات الاتصال (`driver_id`, `token`). تحتوي الدالة على حماية ضد الاستدعاءات المتداخلة (Debounce Flag: `_isInitializingSocket`).
</div>

<div dir="rtl" align="right">
* <b>إعداد المستمعين</b>:
</div>

```dart
void _setupSocketListeners()
```

<div dir="rtl" align="right">
تقوم بربط الأحداث القادمة من السيرفر كالتالي:
1. `connect`: تفعيل مؤشر الاتصال وتدشين الـ Heartbeat عبر الـ Timer.
2. `new_ride_request`: عند وصول طلب رحلة جديد، يتم معالجته فوراً وتوجيهه للواجهة عبر دالة `handleIncomingOrder()`.
3. `cancel_ride`: عند إلغاء الراكب للطلب، يتم إبلاغ `MapDriverController` فوراً لإيقاف وضع الملاحة والعودة للرئيسية عبر `processRideCancelledByPassenger()`.
</div>

<div dir="rtl" align="right">
* <b>إرسال الموقع الفوري للشبكة</b>:
</div>

```dart
void emitLocationToSocket(LatLng pos, double head, double spd)
```

<div dir="rtl" align="right">
تقوم بإرسال حزمة بيانات البث الفعلي (Latitude, Longitude, Heading, Speed, Distance, Status). في حال وجود رحلة نشطة بالحالة `Apply`, `Arrived`, أو `Begin` وبوجود معرف الراكب في الذاكرة، يتم حقن `passenger_id` و `ride_id` تلقائياً لتمكين الراكب من التتبع الحي.
</div>

### 1.3 معالجة الطلبات الواردة (Incoming Order Handler)

<div dir="rtl" align="right">
* <b>معالجة الطلب المستلم</b>:
</div>

```dart
Future<void> handleIncomingOrder(Map<String, dynamic> rideData, String source)
```

<div dir="rtl" align="right">
تتم معالجة الطلب بطريقتين بناءً على حالة التطبيق:
1. **خلفية التطبيق (Background)**:
   * على **iOS**: يتم إرسال إشعار محلي فوري (Ding Tone) ليدعو السائق لفتح التطبيق.
   * على **Android**: يتم إظهار واجهة التراكب السريعة (Overlay View).
2. **واجهة التطبيق (Foreground)**:
   * يتم التحقق من عدم وجود رحلة جارية حالياً (Guard Clause: لمنع تداخل الأحداث أثناء تنفيذ رحلة نشطة).
   * إخفاء أي تراكبات (Overlay Views) مفعلة.
   * التوجيه الفوري للسائق نحو صفحة الطلب المخصصة `/OrderRequestPage` وتمرير معطيات الرحلة المستلمة.
</div>

### 1.4 الاستماع لتدفق الموقع المباشر (GPS Stream Listener)

<div dir="rtl" align="right">
* <b>الاستماع المباشر</b>:
</div>

```dart
Future<void> _subscribeLocationStream()
```

<div dir="rtl" align="right">
يقوم الكنترولر بالاستماع لتغيرات الموقع من الـ GPS، وبثها محلياً للجهات المعنية كالتالي:
1. تحديث إحداثيات السائق الحالية (`myLocation`) والسرعة والاتجاه وتخزينها محلياً في الـ Storage.
2. حساب تراكم المسافة الكلية المقطوعة (`totalDistance`).
3. تحديث خريطة السائق الرئيسية إذا كانت واجهة `HomeCaptain` نشطة.
4. إرسال الإحداثيات وتمريرها مباشرة إلى دالة `handleLocationUpdateFromCentral()` المتواجدة داخل `MapDriverController` (أثناء الذهاب للراكب أو الوجهة).
5. إرسال الإحداثيات وتمريرها مباشرة إلى دالة `handleLocationUpdateFromCentral()` المتواجدة داخل `NavigationController` (أثناء التوجيه خطوة بخطوة).
</div>

---

## 2. إدارة الرحلة النشطة (MapDriverController)

<div dir="rtl" align="right">
يتحكم 
[MapDriverController](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/lib/controller/home/captin/map_driver_controller.dart)
في مراحل تنفيذ الطلب بعد القبول، ورسم المسارات، وعمليات الوصول والإنهاء.
</div>

### 2.1 تحميل المعطيات واستعادة الحالة (Startup Argument Loading)

<div dir="rtl" align="right">
* <b>تحميل المعطيات</b>:
</div>

```dart
Future<void> argumentLoading()
```

<div dir="rtl" align="right">
تعمل هذه الدالة عند فتح الخريطة النشطة، وتقوم بالآتي:
1. قراءة بيانات الرحلة من المتغيرات المستلمة أو استعادتها من التخزين المحلي في حالات انقطاع التطبيق (`BoxName.rideArguments`).
2. تحليل ومعالجة إحداثيات الراكب والوجهة عبر دالة `latlng()`.
3. التحقق من حالة الرحلة المخزنة في الـ Box:
   * إذا كانت الحالة **Begin**: تعني أن الرحلة قد بدأت بالفعل، فيتم تفعيل الأعلام (`isRideStarted = true` و `isRideBegin = true`)، ورسم خط المسار باللون **الأسود/الأزرق** باتجاه **الوجهة النهائية (Passenger Destination)**، وتشغيل عدادات الرحلة وتتبع الخطوات خطوة بخطوة.
   * إذا كانت الحالة غير ذلك: يتم رسم خط المسار باللون **الأصفر** باتجاه **موقع الراكب (Passenger Location)**، وتشغيل محرك التوجيه لتتبع حركة السائق نحو نقطة الالتقاء.
</div>

### 2.2 تحديثات الموقع الواردة من المركز (Location Processing)

<div dir="rtl" align="right">
* <b>استقبال الموقع المركزي</b>:
</div>

```dart
void handleLocationUpdateFromCentral(LatLng newLoc, double posSpeed, double posHeading)
```

<div dir="rtl" align="right">
يتم استدعاء هذه الدالة دورياً من قبل `LocationController` عند كل إحداثي جديد:
1. استخدام آلية التنعيم الفوري لحركة الكاميرا والسيارة على الخريطة عبر الـ `AnimationController` لعمل interpolation سلس ومنع القفزات المفاجئة.
2. استدعاء فحص الملاحة والمسارات التفصيلية عبر `_checkNavigationStep()`.
3. التحقق من اقتراب السائق من وجهته عبر `checkDestinationProximity()`.
</div>

### 2.3 الانتقال بين حالات الرحلة (State Transitions)

<div dir="rtl" align="right">
الحالات كالتالي:
</div>

```
OrderRequestPage: Accept -> Apply -> PassengerLocationMapPage (Yellow Polyline) -> Arrived (Distance < 100m) -> Begin (Distance < 150m) -> Trip to Destination (Blue/Black Polyline) -> Finished -> RatePassenger Page
```

<div dir="rtl" align="right">
* <b>مرحلة وصول السائق للراكب (Arrive)</b>:
</div>

```dart
Future<void> markDriverAsArrived()
```

<div dir="rtl" align="right">
1. التحقق من المسافة الفاصلة بين السائق والراكب؛ يجب أن تكون أقل من 100 متر.
2. إرسال طلب تفعيل حالة الوصول لخادم الرحلات عبر `arrive_ride.php`.
3. بدء تشغيل مؤشر احتساب زمن انتظار السائق للراكب عبر `startTimerToShowDriverWaitPassengerDuration()`.
4. إعادة رسم المسار الجديد للوجهة مباشرة باللون الأزرق استعداداً للمرحلة القادمة.
</div>

<div dir="rtl" align="right">
* <b>مرحلة بدء الرحلة الفعلية (Begin)</b>:
</div>

```dart
Future<void> startRideFromDriver()
```

<div dir="rtl" align="right">
1. التحقق من قرب السائق من الراكب (يجب أن يكون أقل من 150 متر للسماح بالبدء).
2. إيقاف وإعادة ضبط مؤقتات انتظار الراكب.
3. كتابة حالة الرحلة محلياً في الـ Storage وتعيينها إلى `Begin`.
4. مسح الخطوط الصفراء السابقة ورسم مسار الرحلة الفعلي باللون **الأسود/الأزرق** للوجهة.
5. تشغيل عداد الرحلة النشط (`rideIsBeginPassengerTimer`) لتحديث عداد السعر التفاعلي.
6. تشغيل بث التوجيه والملاحة عبر `startListeningStepNavigation()`.
7. بدء تسجيل الصوت لتوثيق الرحلة لأسباب أمنية عبر `AudioRecorderController`.
8. إخطار السيرفر عبر API مخصص `start_ride.php` مع وجود منطق تراجع تلقائي (Rollback) في حال فشل الطلب لإعادة الحالة إلى `Apply`.
</div>

<div dir="rtl" align="right">
* <b>مرحلة إنهاء الرحلة بنجاح (Finish)</b>:
</div>

```dart
Future<void> finishRideFromDriver({bool isFromSlider = false})
Future<void> finishRideFromDriver1({bool isFromSlider = false})
```

<div dir="rtl" align="right">
1. **فحص التحقق المادي للرحلة**: حساب المسافة الإجمالية المخططة للرحلة، والتحقق من أن المسافة التي قطعتها السيارة بالفعل تتجاوز خمس (1/5) المسافة الكلية المطلوبة لمنع الإغلاقات الوهمية أو الخاطئة.
2. في حال مطابقة الشروط، يتم إيقاف تسجيل الصوت وحفظ الملف.
3. تحديث الحالات محلياً في الـ Storage إلى `Finished` وإيقاف تحديثات الموقع وإزالة معرفات الراكب المؤقتة.
4. إرسال حزمة بيانات موحدة ومتكاملة تشتمل على المسافة والوقت والتحقق المالي وخيارات المحفظة لخادم الرحلات عبر API المعاملات الموحد `finish_ride_updates.php`.
5. معالجة وتحديث محفظة السائق بالكامل وإرسال تقرير السلوك الفردي للسائق عبر `DriverBehaviorController`.
6. التوجيه النهائي لصفحة تقييم الراكب `RatePassenger` وتمرير الفاتورة المالية المحسوبة بدقة من السيرفر.
</div>

---

## 3. التوجيه الصوتي والملاحة التفصيلية (Navigation Engine)

<div dir="rtl" align="right">
* <b>الاستماع لتدفق خط الملاحة</b>:
</div>

```dart
void checkForNextStep(LatLng currentPosition)
void _checkNavigationStep(LatLng pos)
```

<div dir="rtl" align="right">
تقوم بمطابقة الموقع الحالي للسائق مع قائمة النقاط والخطوات التوجيهية للرحلة:
1. تحديد الخطوة والمناورة التوجيهية الحالية بناءً على النقطة الأقرب.
2. إذا اقترب السائق من نقطة الانعطاف القادمة (أقل من 30-50 متر)، يتم تفعيل الخطوة التالية وتحديث النصوص الإرشادية.
3. استدعاء محرك التوجيه الصوتي `TextToSpeechController` لنطق التوجيه الجديد باللغة العربية تلقائياً لمنع تشتت السائق أثناء القيادة.
4. قص الأجزاء التي تم قطعها وتجاوزها من المسار المرسوم عبر `_updateTraveledPolylineSmart()` للحفاظ على وضوح ونظافة خط الرحلة على الخريطة.
</div>
