prepare(" UPDATE `ride` SET `status` = ?, `driver_id` = ?, `rideTimeStart` = NOW() WHERE `id` = ? AND `status` IN ('waiting', 'wait') "); $stmtLock->execute([$status, $driverId, $rideId]); if ($stmtLock->rowCount() === 0) { // الرحلة غير متاحة — سائق آخر سبق أو الرحلة ألغيت error_log("[accept_ride] RideID=$rideId not available for DriverID=$driverId (rowCount=0)"); printFailure("Ride not available"); exit; } error_log("[accept_ride] ride DB locked. RideID=$rideId → DriverID=$driverId"); // ═══════════════════════════════════════════════════════════ // STEP B — تزامن primary DB (بعد نجاح القفل) // ═══════════════════════════════════════════════════════════ try { $con->prepare(" UPDATE `ride` SET `driver_id` = ?, `status` = ?, `rideTimeStart` = NOW() WHERE `id` = ? ")->execute([$driverId, $status, $rideId]); error_log("[accept_ride] primary DB synced. RideID=$rideId"); } catch (PDOException $eSync) { // لا نوقف — ride DB هو المرجع error_log("[accept_ride] primary DB sync WARNING: " . $eSync->getMessage()); } // ═══════════════════════════════════════════════════════════ // STEP C — driver_orders (INSERT أو UPDATE بسطر واحد آمن) // ON DUPLICATE KEY يمنع race condition ثانية على هذا الجدول // ═══════════════════════════════════════════════════════════ try { $con->prepare(" INSERT INTO `driver_orders` (`driver_id`, `order_id`, `status`, `created_at`) VALUES (?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE `driver_id` = VALUES(`driver_id`), `status` = VALUES(`status`), `created_at` = NOW() ")->execute([$driverId, $rideId, $status]); } catch (PDOException $eOrders) { error_log("[accept_ride] driver_orders WARNING: " . $eOrders->getMessage()); } // ═══════════════════════════════════════════════════════════ // STEP D — جلب بيانات السائق للراكب // ═══════════════════════════════════════════════════════════ $driverInfo = []; $stmtDriver = $con->prepare(" SELECT d.id AS driver_id, d.first_name, d.last_name, d.gender, d.phone, c.make, c.model, c.car_plate, c.year, c.color, c.color_hex, (SELECT ROUND(AVG(rating), 2) FROM ratingDriver WHERE driver_id = d.id) AS ratingDriver, dt.token FROM driver d LEFT JOIN CarRegistration c ON c.driverID = d.id LEFT JOIN driverToken dt ON dt.captain_id = d.id WHERE d.id = ? LIMIT 1 "); $stmtDriver->execute([$driverId]); $driverRaw = $stmtDriver->fetch(PDO::FETCH_ASSOC); if ($driverRaw) { $encryptedFields = ['first_name', 'last_name', 'gender', 'phone', 'car_plate', 'token']; foreach ($driverRaw as $key => $value) { $driverInfo[$key] = (in_array($key, $encryptedFields) && !empty($value)) ? $encryptionHelper->decryptData($value) : $value; } $driverInfo['driverName'] = trim(($driverInfo['first_name'] ?? '') . ' ' . ($driverInfo['last_name'] ?? '')); $driverInfo['ratingDriver'] = $driverInfo['ratingDriver'] ?: "5.0"; } // ═══════════════════════════════════════════════════════════ // STEP E — جلب passenger_id وإرسال الإشعارات // ═══════════════════════════════════════════════════════════ $passengerId = $con->prepare("SELECT passenger_id FROM ride WHERE id = ? LIMIT 1"); $passengerId->execute([$rideId]); $passengerIdValue = $passengerId->fetchColumn(); if ($passengerIdValue) { // Socket — real-time update على خريطة الراكب if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passengerIdValue, [ 'status' => 'accepted', 'ride_id' => $rideId, 'driver_id' => $driverId, 'driver_info' => $driverInfo, ]); } // FCM — push notification if (!empty($passengerToken)) { sendFCM_Internal( $passengerToken, "تم قبول رحلتك", "الكابتن " . ($driverInfo['driverName'] ?? '') . " في طريقه إليك", ['ride_id' => (string) $rideId, 'driver_info' => $driverInfo], "ride_accepted", false ); } } // ═══════════════════════════════════════════════════════════ // STEP F — تنظيف السوق (أبلغ location server إن الرحلة محجوزة) // ═══════════════════════════════════════════════════════════ sendToLocationServer('ride_taken_event', [ 'ride_id' => $rideId, 'taken_by_driver_id' => $driverId, ]); error_log("[accept_ride] SUCCESS. RideID=$rideId accepted by DriverID=$driverId"); // ═══════════════════════════════════════════════════════════ // STEP G — رد النجاح للسائق (نفس بنية الرد القديمة) // ═══════════════════════════════════════════════════════════ echo json_encode([ "status" => "success", "message" => "Ride Accepted", "data" => $driverInfo, ]); } catch (PDOException $e) { error_log("[accept_ride] CRITICAL: " . $e->getMessage()); printFailure("Server error"); }