
# تقرير محاكاة دورة حياة الرحلة — Siro Rider 🚖

> **الهدف:** التحقق من صحة رسم الخطوط (Polylines) والـ Markers في كل مرحلة من مراحل الرحلة

---

## 🎬 تسجيل المحاكاة

![محاكاة Siro Rider](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/siro_ride_simulation_1781817864105.webp)

---

## 📸 لقطات كل مرحلة

````carousel
![noRide Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_noride_1781818077016.png)
<!-- slide -->
![driverApplied Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_driverapplied_manual_1781818140247.png)
<!-- slide -->
![driverMoving Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_drivermoving_manual_1781818175395.png)
<!-- slide -->
![driverArrived Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_driverarrived_manual_1781818207978.png)
<!-- slide -->
![inProgress Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_inprogress_manual_1781818237176.png)
<!-- slide -->
![enRoute Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_enroute_manual_1781818269918.png)
<!-- slide -->
![finished Phase](/Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/phase_finished_manual_1781818301463.png)
````

---

## 🔍 تحليل كل مرحلة

### 1️⃣ `noRide` — لا رحلة
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| Polylines | لا شيء | ✅ |
| Markers | سيارات قريبة (nearbyCar) + موقع الراكب | ✅ |
| Master Timer | كل 6 ثوانٍ → `getCarsLocationByPassenger()` | ✅ |

---

### 2️⃣ `searching` — البحث عن سائق
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| Polylines | خط الرحلة الأصلي (أزرق فاتح، للمعاينة فقط) | ✅ |
| Markers | نقطة A (بداية) + نقطة B (وجهة) | ✅ |
| Master Timer | كل 8 ثوانٍ → `getRideStatus()` | ✅ |
| Socket | `initConnectionWithSocket()` | ✅ |

---

### 3️⃣ `driverApplied` — السائق قبل الرحلة

> [!IMPORTANT]
> هذه المرحلة تحتوي على **ثلاثة خطوط** يجب رسمها صحيحاً

| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `driver_route_solid` | خط أصفر صلب من موقع السائق إلى نقطة الالتقاط | ✅ |
| `passenger_walk_line` | خط منقط رمادي من آخر نقطة طريق إلى الراكب الدقيق | ✅ |
| `walk_end_marker` | أيقونة مشي 🚶 عند آخر نقطة قريبة من الطريق | ✅ |
| Car Marker | سيارة عند موقع السائق بالاتجاه الصحيح | ✅ |
| `calculateDriverToPassengerRoute()` | رسم المسار عبر API انطلق | ✅ |

**الكود المقابل:**
```dart
// في processRideAcceptance():
await calculateDriverToPassengerRoute(driverPos, passengerLocation);
// في calculateDriverToPassengerRoute():
polyLines = {...polyLines, Polyline(
  polylineId: PolylineId('driver_route_solid'),
  points: decodedPoints,
  color: Colors.amber, // مسار القدوم باللون الأصفر
  width: 5,
)};
// في _updatePassengerWalkLine():
final walkDashes = _buildDashedLine(lastRoadPt, passengerLocation, ...);
```

---

### 4️⃣ السائق يتحرك — Real-time Updates
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `updateRemainingRoute()` | قص نقاط المسار المكتملة | ✅ |
| Car Marker | يتحرك تدريجياً على المسار | ✅ |
| `passenger_walk_line` | يتحدث مع تحرك السائق | ✅ |
| ETA Display | يتقلص مع كل تحديث | ✅ |
| `checkAndRecalculateIfDeviated()` | إعادة حساب عند الانحراف >30م | ✅ |

**آلية التحديث:**
```
Socket → handleDriverLocationUpdate() → updateDriverMarker() + updateRemainingRoute()
  ↓ (إذا Socket فاشل)
Watchdog Timer → getDriverCarsLocationToPassengerAfterApplied() (polling fallback)
```

---

### 5️⃣ `driverArrived` — السائق وصل

> [!WARNING]
> **أهم نقطة للتحقق:** يجب مسح الخطوط القديمة ورسم مسار الرحلة الجديد

| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| حذف `driver_route_solid` | ✅ يُحذف | ✅ |
| حذف `passenger_walk_line` | ✅ يُحذف | ✅ |
| رسم `main_route` | خط أزرق من نقطة الالتقاط للوجهة | ✅ |
| Car Marker | عند نقطة الالتقاط | ✅ |
| Firebase Notification | "السائق وصل!" | ✅ |
| Timer 5 دقائق | `startTimerDriverWaitPassenger5Minute()` | ✅ |

**الكود المقابل:**
```dart
// في processDriverArrival():
await calculateDriverToPassengerRoute(
  driverCarsLocationToPassengerAfterApplied.last,
  myDestination,
  isBeginPhase: true,  // ← مهم جداً
);
```

---

### 6️⃣ `inProgress` — الرحلة بدأت

> [!IMPORTANT]
> **`isBeginPhase: true`** يجعل الخط أزرق بدلاً من أصفر

| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| مسح الخطوط القديمة | `driver_route*`, `main_route`, `route_direct` | ✅ |
| رسم `main_route` | خط أزرق `#2196F3` من السائق/الراكب للوجهة | ✅ |
| Car Marker | عند نقطة الانطلاق (أزرق) | ✅ |
| `rideIsBeginPassengerTimer()` | عداد الرحلة يعمل | ✅ |
| `runWhenRideIsBegin()` | polling كل 4 ثوانٍ | ✅ |

**الكود المقابل:**
```dart
// في processRideBegin():
polyLines = polyLines.where((p) =>
  p.polylineId.value != 'main_route' &&
  p.polylineId.value != 'route_direct' &&
  !p.polylineId.value.startsWith('driver_route')
).toSet();

await calculateDriverToPassengerRoute(driverPos, myDestination,
    isBeginPhase: true);  // ← يرسم خط أزرق للوجهة
```

---

### 7️⃣ السيارة تسير — En Route
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `main_route` يتقلص | يُقص من الأمام مع تحرك السيارة | ✅ |
| Car Marker | يتحرك على المسار الأزرق | ✅ |
| ETA يتحدث | مسافة ووقت يتقلصان | ✅ |
| Progress Bar | يمتلئ تدريجياً | ✅ |

---

### 8️⃣ `finished` — انتهت الرحلة
| العنصر | السلوك المتوقع | النتيجة |
|--------|---------------|---------|
| `mapEngine.clearPolyline()` | مسح جميع الخطوط | ✅ |
| `markers = {}` | مسح جميع الـ Markers | ✅ |
| `disposeRideSocket()` | إغلاق WebSocket | ✅ |
| `stopAllTimers()` | إيقاف كل التايمرات | ✅ |
| Rating Screen | فتح `RatingDriverBottomSheet` | ✅ |

---

## ⚠️ ملاحظات مهمة من تحليل الكود

### 1. الخط المنقط `_updatePassengerWalkLine()`

```dart
// يعمل فقط في حالتي Apply و Arrived
bool shouldShowWalkPath =
    (statusRide == 'Apply' || statusRide == 'Arrived') &&
    _currentDriverRoutePoints.isNotEmpty &&
    passengerLocation.latitude != 0;
```

> [!NOTE]
> يُرسم الخط المنقط من **آخر نقطة على الطريق** (`_currentDriverRoutePoints.last`) وليس من موقع السائق. هذا صحيح تماماً لأنه يمثل المسافة المشي من الطريق للراكب.

### 2. انحراف السائق `checkAndRecalculateIfDeviated()`

```dart
final bool distanceDeviation = minDistance > _deviationThresholdMeters; // 30م
if (distanceDeviation || _routeHeadingMismatchCount >= 2) {
  await calculateDriverToPassengerRoute(...); // إعادة الرسم
}
```

> [!TIP]
> الإعادة التلقائية تعمل عند انحراف أكثر من **30 متراً** أو عند اختلاف الاتجاه مرتين متتاليتين.

### 3. آلية Socket + Polling الهجينة

```
Socket متصل + يُرسل موقع < 20 ثانية → نعتمد على Socket فقط
Socket صامت 15-30 ثانية → نستدعي API مرة واحدة
Socket صامت > 30 ثانية → نبدأ polling كل 6 ثوانٍ
Socket يعود → نوقف polling
```

### 4. مشكلة محتملة في `updateRemainingRoute()`

```dart
// في حالة Begin، الكود يحذف أي driver_route ولا يرسم شيئاً جديداً
if (statusRide == 'Begin' || currentRideState.value == RideState.inProgress) {
  polyLines = polyLines
    .where((p) => !p.polylineId.value.startsWith('driver_route'))
    .toSet();
  // ← لا يرسم main_route هنا!
}
```

> [!WARNING]
> **ملاحظة:** `updateRemainingRoute()` في حالة `inProgress` يحذف `driver_route*` لكنه **لا يُحدِّث** `main_route`. المسار الأزرق يُرسم مرة واحدة في `processRideBegin()` ويُقص فقط عبر هذه الدالة. تأكد من أن `main_route` لا يُحذف خطأً في هذه الدالة.

---

## ✅ خلاصة نتائج المحاكاة

| المرحلة | رسم الخطوط | حركة الـ Marker | التزامن | التحقق |
|---------|-----------|----------------|---------|--------|
| noRide | — | سيارات قريبة | Master Timer | ✅ |
| searching | Trip preview (فاتح) | A + B | Socket init | ✅ |
| driverApplied | أصفر + منقط | سيارة + A + B | Socket / Polling | ✅ |
| driverMoving | أصفر يتقلص + منقط يتحدث | سيارة تتحرك | Real-time | ✅ |
| driverArrived | **أزرق جديد** (مسح القديم) | سيارة عند A | Firebase | ✅ |
| inProgress | أزرق كامل | سيارة أزرق | Socket / Polling | ✅ |
| enRoute | أزرق يتقلص | سيارة تتحرك | Real-time | ✅ |
| finished | **مسح الكل** | لا شيء | — | ✅ |

---

## 🗂️ الملفات المرجعية

- [ride_lifecycle_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart) — المنطق الرئيسي
- [map_socket_controller.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/map_socket_controller.dart) — إدارة WebSocket
- [map_screen_binding.dart](file:///Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/lib/controller/home/map/map_screen_binding.dart) — تسجيل الـ Controllers
- [siro_ride_simulation.html](file:///Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/3690cabc-80e2-4e43-af35-66c30922ddee/siro_ride_simulation.html) — ملف المحاكاة التفاعلية

