<?php
// ═══════════════════════════════════════════════════════════════
// driver/ride/accept_ride.php
// PURPOSE : قبول رحلة — ride DB هو المرجع، primary DB يتزامن بعده
// RACE     : Optimistic lock عبر WHERE status IN ('waiting','wait')
// ═══════════════════════════════════════════════════════════════

include "../../connect.php";

try {
    $con_ride = Database::get('ride');
} catch (Exception $e) {
    error_log("[accept_ride] Failed to connect to Ride Database: " . $e->getMessage());
    printFailure("Database connection failed");
    exit;
}

// ── 1. Input & Validation ──────────────────────────────────────
$rideId = filterRequest("id");
$driverId = filterRequest("driver_id");
$status = filterRequest("status");       // القيمة التي يرسلها التطبيق: 'accepted'
$passengerToken = filterRequest("passengerToken");

if (empty($rideId) || empty($driverId)) {
    printFailure("Missing required parameters");
    exit;
}

// status whitelist — لا نقبل قيمة عشوائية من التطبيق
$allowedStatuses = ['accepted', 'Apply'];
if (!in_array($status, $allowedStatuses, true)) {
    $status = 'accepted'; // fallback آمن
}

error_log("[accept_ride] DriverID=$driverId attempting RideID=$rideId");

try {
    // ═══════════════════════════════════════════════════════════
    // STEP A — القفل على ride DB (المرجع الأساسي)
    // Optimistic lock: نغير فقط إذا status لا يزال 'waiting' أو 'wait'
    // السائق الأول الذي يصل يربح — الباقي يجدون rowCount=0
    // ═══════════════════════════════════════════════════════════
    $stmtLock = $con_ride->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 C.1 — تحديث جدول waitingRides حتى لا تظهر للكباتن الآخرين
    // ═══════════════════════════════════════════════════════════
    try {
        $con->prepare("UPDATE `waitingRides` SET `status` = 'Apply' WHERE `id` = ?")->execute([$rideId]);
    } catch (PDOException $eWaiting) {
        error_log("[accept_ride] waitingRides WARNING: " . $eWaiting->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,
            (SELECT COUNT(*) FROM ratingDriver WHERE driver_id = d.id) AS ratingCount,
            (SELECT COUNT(*) FROM ride WHERE driver_id = d.id AND status IN ('Finished', 'finished')) AS completedRides,
            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";
        $ratingValue = (float) $driverInfo['ratingDriver'];
        $ratingCount = (int) ($driverInfo['ratingCount'] ?? 0);
        $completedRides = (int) ($driverInfo['completedRides'] ?? 0);
        if ($ratingValue >= 4.8 && $ratingCount >= 50 && $completedRides >= 100) {
            $driverInfo['driverTier'] = 'Professional driver';
        } elseif ($ratingValue >= 4.5 && $ratingCount >= 15 && $completedRides >= 30) {
            $driverInfo['driverTier'] = 'Trusted driver';
        } else {
            $driverInfo['driverTier'] = 'Verified driver';
        }
    }

    // ═══════════════════════════════════════════════════════════
    // 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,
                "", // تفريغ العنوان للإرسال الصامت
                "", // تفريغ المحتوى للإرسال الصامت
                ['ride_id' => (string) $rideId, 'driver_info' => $driverInfo, 'status' => 'accepted'],
                "Accepted Ride",
                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");
}
