SCHEDULE_MAX_DAYS_AHEAD * 24 * 60) { jsonError('يمكنك الحجز حتى ' . SCHEDULE_MAX_DAYS_AHEAD . ' يومين مقدماً فقط'); } // ── هامش البحث عن سائق ────────────────────────────────────── // ‏نشتقّه من المسافة بدل أن نسأل الراكب: رحلة مطار بعيدة تحتاج وقتاً // ‏أطول لإيجاد سائق وللوصول إليه من رحلة داخل الحي. $leadMinutes = 15; if ($distance > 25) { $leadMinutes = 40; } elseif ($distance > 10) { $leadMinutes = 25; } try { // ── منع الحجز المزدوج ─────────────────────────────────── // ‏راكب له حجزان في نفس النصف ساعة غالباً ضغط مرتين. الحجز المكرر // ‏ينتج رحلتين حقيقيتين ويُحمّله رسمَي إلغاء. $dup = $con->prepare(" SELECT id FROM scheduled_rides WHERE passenger_id = ? AND status = 'scheduled' AND ABS(TIMESTAMPDIFF(MINUTE, scheduled_at, ?)) < 30 LIMIT 1 "); $dup->execute([$passengerId, date('Y-m-d H:i:s', $ts)]); if ($dup->fetchColumn()) { jsonError('You already have a booking around this time', 409); } $ins = $con->prepare(" INSERT INTO scheduled_rides (passenger_id, start_location, end_location, start_name, end_name, car_type, distance, duration, estimated_price, scheduled_at, lead_minutes, note) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) "); $ins->execute([ $passengerId, $startLocation, $endLocation, $startName, $endName, $carType, $distance, $duration, $estimated, date('Y-m-d H:i:s', $ts), $leadMinutes, $note ? mb_substr($note, 0, 255) : null, ]); $id = (int) $con->lastInsertId(); error_log("[scheduled] حجز #$id للراكب $passengerId في " . date('Y-m-d H:i', $ts) . " (هامش {$leadMinutes}د)"); jsonSuccess([ 'id' => $id, 'scheduled_at' => date('Y-m-d H:i:s', $ts), 'lead_minutes' => $leadMinutes, // ‏نصرّح بأن السعر تقديري: الراكب يجب أن يعرف أن الرقم قد يتغيّر. 'price_is_estimate' => true, ], 'Ride scheduled'); } catch (PDOException $e) { error_log('[scheduled/add] ' . $e->getMessage()); jsonError('DB Error', 500); }