getMessage()); jsonError("Service unavailable", 503); } // ‏من يسأل: راكب يقيّم سائقه، أو سائق يقيّم راكبه. $role_ = filterRequest("role") === 'driver' ? 'driver' : 'passenger'; // ‏الهوية من الـJWT لا من الطلب — وإلا قرأ أي أحد رحلات غيره. $userId = $user_id ?? ''; if (empty($userId)) { jsonError("Unauthorized", 401); } // ‏نافذة معقولة: تقييم رحلة نسيها صاحبها بلا قيمة، ويزعجه. const PENDING_RATING_WINDOW_DAYS = 7; // ‏عدد الرحلات التي نفحصها. آخر رحلة غير مقيّمة عملياً ضمن آخر قليل، // ‏فلا داعي لمسح تاريخ المستخدم كله. const PENDING_RATING_SCAN_LIMIT = 10; try { // ── ١) آخر الرحلات المنتهية من قاعدة الرحلات ────────────── $col = $role_ === 'driver' ? 'driver_id' : 'passenger_id'; $stmt = $con_ride->prepare(" SELECT id, driver_id, passenger_id, price, carType, start_location, end_location, rideTimeFinish FROM ride WHERE `$col` = ? AND status = 'Finished' AND rideTimeFinish >= NOW() - INTERVAL " . PENDING_RATING_WINDOW_DAYS . " DAY ORDER BY rideTimeFinish DESC LIMIT " . PENDING_RATING_SCAN_LIMIT ); $stmt->execute([$userId]); $rides = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($rides)) { jsonSuccess(['pending' => false], "No pending rating"); } // ── ٢) أيّها مقيَّم؟ استعلام واحد لكلها ─────────────────── $ids = array_column($rides, 'id'); $ph = implode(',', array_fill(0, count($ids), '?')); // ‏الراكب يقيّم السائق في ratingDriver (العمود ride_id)، // ‏والسائق يقيّم الراكب في ratingPassenger (العمود rideId). $ratedSql = $role_ === 'driver' ? "SELECT rideId AS rid FROM ratingPassenger WHERE rideId IN ($ph)" : "SELECT ride_id AS rid FROM ratingDriver WHERE ride_id IN ($ph)"; $stmtRated = $con->prepare($ratedSql); $stmtRated->execute($ids); $rated = array_flip($stmtRated->fetchAll(PDO::FETCH_COLUMN)); // ── ٣) أول رحلة غير مقيّمة (الأحدث أولاً) ───────────────── $target = null; foreach ($rides as $r) { if (!isset($rated[$r['id']]) && !isset($rated[(string) $r['id']])) { $target = $r; break; } } if (!$target) { jsonSuccess(['pending' => false], "No pending rating"); } // ── ٤) اسم الطرف الآخر ──────────────────────────────────── // ‏من primary: جداول driver/passengers تعيش هناك، والاسم مشفَّر. $otherId = $role_ === 'driver' ? $target['passenger_id'] : $target['driver_id']; $otherName = ''; try { $table = $role_ === 'driver' ? 'passengers' : 'driver'; $stmtName = $con->prepare("SELECT first_name FROM `$table` WHERE id = ? LIMIT 1"); $stmtName->execute([$otherId]); $raw = $stmtName->fetchColumn(); if ($raw && !empty($encryptionHelper)) { $dec = $encryptionHelper->decryptData($raw); $otherName = ($dec !== false && $dec !== '') ? $dec : ''; } } catch (Throwable $e) { // ‏الاسم تحسين لا شرط — الشاشة تعمل بدونه. error_log("[pending_rating] تعذّر جلب اسم الطرف الآخر: " . $e->getMessage()); } jsonSuccess([ 'pending' => true, 'rideId' => (string) $target['id'], 'targetId' => (string) $otherId, 'targetName' => $otherName, 'price' => $target['price'], 'carType' => $target['carType'], 'finishedAt' => $target['rideTimeFinish'], ], "Pending rating found"); } catch (PDOException $e) { error_log("[pending_rating] " . $e->getMessage()); jsonError("DB Error", 500); }