<?php
// acceptRide.php

// 1. Include Database Connection
// This file connects to both the Main DB ($con) and the Ride DB ($con_ride).
require_once __DIR__ . '/../../connect.php'; 

// 2. Input Validation & Filtering
// We sanitize the inputs to prevent SQL injection or XSS.
$rideId         = filterRequest("id"); 
$driverId       = filterRequest("driver_id");
$status         = filterRequest("status"); // Expected: 'Apply' or 'accepted'
$passengerToken = filterRequest("passengerToken");

// Check if critical data is missing
if (!$rideId || !$driverId) {
    jsonError("Missing required parameters.");
    exit;
}



try {
    // =================================================================================
    // 3. 🔒 ATOMIC UPDATE (The Race Condition Solver)
    // We attempt to update the ride status ONLY if it is currently 'waiting'.
    // This prevents two drivers from accepting the same ride simultaneously.
    // We execute this on the Remote/Ride Database first ($con_ride).
    // =================================================================================
    $stmtRemote = $con_ride->prepare("
        UPDATE `ride` 
        SET `status` = ?, `driver_id` = ?, `rideTimeStart` = NOW() 
        WHERE `id` = ? AND `status` IN ('waiting', 'wait')
    ");
    $stmtRemote->execute([$status, $driverId, $rideId]);
    
    // Check if the update actually changed a row.
    // If rowCount > 0, IT MEANS SUCCESS! This driver won the ride.
    if ($stmtRemote->rowCount() > 0) {
        
        // 4. Synchronization: Update Local Database
        // Now that we secured the ride, we update the main server's DB ($con) to match.
        if (isset($con)) {
             $stmtLocal = $con->prepare("UPDATE `ride` SET `driver_id` = ?, `status` = ?, `rideTimeStart` = NOW() WHERE id = ?");
             $stmtLocal->execute([$driverId, $status, $rideId]);
        }

        // 5. Update/Insert Driver Orders Table
        // This tracks the driver's history or active orders.
        $checkSql = "SELECT `order_id` FROM `driver_orders` WHERE `order_id` = ?";
        $checkStmt = $con->prepare($checkSql);
        $checkStmt->execute([$rideId]);

        if ($checkStmt->rowCount() > 0) {
            // If entry exists, update it
            $updateSql = "UPDATE `driver_orders` SET `driver_id` = ?, `status` = ?, `created_at` = NOW() WHERE `order_id` = ?";
            $con->prepare($updateSql)->execute([$driverId, $status, $rideId]);
        } else {
            // If not, insert new record
            $insertSql = "INSERT INTO `driver_orders` (`driver_id`, `order_id`, `created_at`, `status`) VALUES (?, ?, NOW(), ?)";
            $con->prepare($insertSql)->execute([$driverId, $rideId, $status]);
        }

        // =================================================================
        // 6. 👤 GET DRIVER INFO (For the Passenger)
        // We need to fetch driver details (Car, Name, Rating) to show to the passenger.
        // =================================================================
        
        $driverInfo = [];
        
        $sqlDetails = "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 = ?";

        $stmtDetails = $con->prepare($sqlDetails);
        $stmtDetails->execute([$driverId]);
        $driverRawData = $stmtDetails->fetch(PDO::FETCH_ASSOC);

        if ($driverRawData) {
            // List of encrypted fields that need decryption
            $fieldsToDecrypt = ['first_name', 'last_name', 'gender', 'phone', 'car_plate', 'token'];
            
            foreach ($driverRawData as $key => $value) {
                if (in_array($key, $fieldsToDecrypt) && !empty($value)) {
                    // Decrypt sensitive data
                    $driverInfo[$key] = $encryptionHelper->decryptData($value);
                } else {
                    $driverInfo[$key] = $value;
                }
            }
            
            // Format Full Name
            $driverInfo['driverName'] = trim(($driverInfo['first_name'] ?? '') . ' ' . ($driverInfo['last_name'] ?? ''));
            
            // Default rating if null
            if (empty($driverInfo['ratingDriver'])) {
                $driverInfo['ratingDriver'] = "5.0"; 
            }
        }

        // =================================================================
        // 7. 🔔 NOTIFY PASSENGER (Socket + FCM)
        // Inform the passenger that a driver has been found.
        // =================================================================
        
        // Fetch Passenger ID based on Ride ID
        $stmtPas = $con->prepare("SELECT passenger_id FROM ride WHERE id = ?");
        $stmtPas->execute([$rideId]);
        $passenger_id = $stmtPas->fetchColumn();

        if ($passenger_id) {
            // A. Send Socket Notification (Real-time update on map)
            if (function_exists('notifyPassengerOnRideServer')) {
                notifyPassengerOnRideServer($passenger_id, [
                    'status'      => 'accepted',
                    'ride_id'     => $rideId,
                    'driver_id'   => $driverId,
                    'driver_info' => $driverInfo 
                ]);
            }

            // B. Send FCM Notification (Push Notification)
            if (!empty($passengerToken)) {
                // Using the standardized FCM function
                sendFCM_Internal(
                    $passengerToken, 
                    "Ride Accepted 🚖", // Title
                    "Captain " . ($driverInfo['driverName'] ?? 'Driver') . " is coming to you.", // Body
                    ['ride_id' => (string)$rideId, 'driver_info' => $driverInfo], // Data Payload
                    "Accepted Ride", // Category
                    false // Not a topic
                );
            }
        }

        // =================================================================
        // 8. 🧹 MARKETPLACE CLEANUP (Notify Location Server)
        // Crucial Step: We tell the Location Server that this ride is taken.
        // The Location Server will:
        //    1. Remove the ride from Redis (geo:rides:waiting).
        //    2. Broadcast 'ride_taken' to other drivers to remove it from their screens.
        // =================================================================
        sendToLocationServer('ride_taken_event', [
            'ride_id' => $rideId,
            'taken_by_driver_id' => $driverId
        ]);

        // 9. Final Response to the Driver App
        echo json_encode([
            "status"  => "success", 
            "message" => "Ride Accepted", 
            "data"    => $driverInfo
        ]);
        
    } else {
        // Failure: This means rowCount was 0.
        // Reason: The ride status was NOT 'waiting' (another driver took it milliseconds ago).
        jsonError("Ride not available (Already taken)");
    }

} catch (Exception $e) {
    // Handle unexpected errors
    jsonError("Error: " . $e->getMessage());
}
?>