<?php
require_once __DIR__ . '/../../connect.php';

$distance = (float) filterRequest("distance");
$duration = (float) filterRequest("durationToRide");
$promo_code = filterRequest("promo_code");
$passenger_id = filterRequest("passenger_id");
$promo_code_id = filterRequest("promo_code_id") ? filterRequest("promo_code_id") : 0;
$country = filterRequest("country");

$startNameAddress = filterRequest("startNameAddress");
$endNameAddress = filterRequest("endNameAddress");
$destLat = (float) filterRequest("destLat");
$destLng = (float) filterRequest("destLng");
$passengerLat = (float) filterRequest("passengerLat");
$passengerLng = (float) filterRequest("passengerLng");
$activeMenuWaypointCount = (int) filterRequest("activeMenuWaypointCount");

if (!$country) {
    echo json_encode(["status" => "failure", "message" => "Country parameter is required"]);
    exit;
}

$price = 0.0;
$price_for_driver = 0.0;
$withCommission = 0.0;
$kazan = 0.0;
$isNightFare = false;

// Common variables
date_default_timezone_set('Asia/Damascus');
$currentTime = new DateTime();
$hour = (int)$currentTime->format('H');

switch ($country) {
    case 'Syria':
        $minFare = 150.0;
        break;
    case 'Egypt':
        $minFare = 20.0;
        break;
    case 'Jordan':
        $minFare = 1.0;
        break;
    default:
        $minFare = 0.0;
        break;
}

// Fetch kazan from DB for the specified country
$sql = "SELECT * FROM `kazan` WHERE country = :country LIMIT 1";
$stmt = $con->prepare($sql);
$stmt->execute([':country' => $country]);
$kazanRow = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$kazanRow) {
    echo json_encode(["status" => "failure", "message" => "No pricing available for this country"]);
    exit;
}

$result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng);
$price = $result['price'];
$price_for_driver = $result['price_for_driver'];
$withCommission = $result['withCommission'];
$kazan = $result['kazan'];
$isNightFare = $result['isNightFare'];

// ----------------------------------------------------------------------
// Helper Functions for Countries
// ----------------------------------------------------------------------

function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng) {
    $comfortPrice = (float) $kazanRow['comfortPrice'];
    $speedPrice = (float) $kazanRow['speedPrice'];
    $familyPrice = (float) $kazanRow['familyPrice'];
    $deliveryPrice = (float) $kazanRow['deliveryPrice'];
    $naturePrice = (float) $kazanRow['naturePrice'];
    $heavyPrice = (float) $kazanRow['heavyPrice'];
    $latePrice = (float) $kazanRow['latePrice'];
    $kazanPercent = (float) $kazanRow['kazan'];

    // === General Settings ===
    $minBillableKm = 0.2;
    $airportAddon = 0.0;
    $damascusAirportBoundAddon = 0.0;
    
    switch ($country) {
        case 'Egypt':
            $airportAddon = 35.0;
            break;
        case 'Jordan':
            $airportAddon = 5.0;
            break;
        default: // Syria
            $airportAddon = 200.0;
            $damascusAirportBoundAddon = 1400.0;
            break;
    }
    
    $longSpeedThresholdKm = 40.0;
    $longSpeedPerKm = 26.0;

    $mediumDistThresholdKm = 25.0;
    $longDistThresholdKm = 35.0;
    $longTripPerMin = 6.0;
    $minuteCapMedium = 60;
    $minuteCapLong = 80;
    $freeMinutesLong = 10;

    $extraReduction100 = 0.07;
    $maxReductionCap = 0.35;

    $totalMinutes = floor($duration / 60);

    $airportCtx = (stripos($startNameAddress, 'airport') !== false || stripos($startNameAddress, 'مطار') !== false || stripos($endNameAddress, 'airport') !== false || stripos($endNameAddress, 'مطار') !== false);
    $clubCtx = (stripos($startNameAddress, 'club') !== false || stripos($startNameAddress, 'ديسكو') !== false || stripos($endNameAddress, 'club') !== false || stripos($endNameAddress, 'ديسكو') !== false);

    $northLat = 33.415313;
    $southLat = 33.400265;
    $eastLng = 36.531505;
    $westLng = 36.499687;
    $damascusAirportBoundCtx = ($destLat <= $northLat && $destLat >= $southLat && $destLng <= $eastLng && $destLng >= $westLng);
    $isInDamascusAirportBoundCtx = ($passengerLat <= $northLat && $passengerLat >= $southLat && $passengerLng <= $eastLng && $passengerLng >= $westLng);

    $billableDistance = ($distance < $minBillableKm) ? $minBillableKm : $distance;
    $isLongSpeed = $billableDistance > $longSpeedThresholdKm;
    $perKmSpeedBaseFromServer = $speedPrice;
    $perKmSpeed = $isLongSpeed ? $longSpeedPerKm : $perKmSpeedBaseFromServer;

    $reductionPct40 = 0.0;
    if ($perKmSpeedBaseFromServer > 0) {
        $r = 1.0 - ($longSpeedPerKm / $perKmSpeedBaseFromServer);
        $reductionPct40 = max(0.0, min($maxReductionCap, $r));
    }
    $reductionPct100 = max(0.0, min($maxReductionCap, $reductionPct40 + $extraReduction100));

    $distanceReduction = 0.0;
    if ($billableDistance > 100.0) {
        $distanceReduction = $reductionPct100;
    } else if ($billableDistance > 40.0) {
        $distanceReduction = $reductionPct40;
    }

    date_default_timezone_set('Asia/Damascus');
    $hour = (int)date('H');
    $effectivePerMin = $naturePrice;
    if ($hour >= 21 || $hour < 1) {
        $effectivePerMin = $latePrice;
    } else if ($hour >= 1 && $hour < 5) {
        $effectivePerMin = $clubCtx ? ($latePrice * 2) : $latePrice;
    } else if ($hour >= 14 && $hour <= 17) {
        $effectivePerMin = $heavyPrice;
    }

    $billableMinutes = $totalMinutes;
    if ($billableDistance > $longDistThresholdKm) {
        $effectivePerMin = $longTripPerMin;
        $capped = ($billableMinutes > $minuteCapLong) ? $minuteCapLong : $billableMinutes;
        $billableMinutes = max(0, $capped - $freeMinutesLong);
    } else if ($billableDistance > $mediumDistThresholdKm) {
        $effectivePerMin = $longTripPerMin;
        $billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes;
    }

    $fare = $billableDistance * $perKmSpeed;
    $fare += $billableMinutes * $effectivePerMin;
    if ($airportCtx) $fare += $airportAddon;
    if ($damascusAirportBoundCtx || $isInDamascusAirportBoundCtx) {
        $fare += $damascusAirportBoundAddon;
    }

    $price = max($fare, $minFare);

    // Apply kazan (e.g. 11%)
    $withCommission = ceil($price * (1 + $kazanPercent / 100));
    $kazan = $withCommission - $price;
    $price_for_driver = $price;

    return [
        'price' => $price,
        'price_for_driver' => $price_for_driver,
        'withCommission' => $withCommission,
        'kazan' => $kazan,
        'isNightFare' => false
    ];
}

// 2. Validate Promo Code
$discount = 0;
if (!empty($promo_code)) {
    $sqlPromo = "SELECT amount FROM `promos` 
                 WHERE promo_code = :promo_code 
                 AND (passengerID = :passenger_id OR passengerID LIKE '%all%')
                 AND validity_start_date <= CURDATE() 
                 AND validity_end_date >= CURDATE()";
    $stmtPromo = $con->prepare($sqlPromo);
    $stmtPromo->execute([
        ':promo_code' => $promo_code,
        ':passenger_id' => $passenger_id
    ]);
    if ($stmtPromo->rowCount() > 0) {
        $promoData = $stmtPromo->fetch(PDO::FETCH_ASSOC);
        $discount = (float) $promoData['amount'];
    }
}

// 3. Fetch Passenger Wallet (Negative Balance / Debt)
// Using Redis for ultra-fast reads, with a fallback to the Payment Server API.
$negativeBalance = 0;
if (!empty($passenger_id)) {
    try {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redisKey = "passenger_debt_" . $passenger_id;
        
        $redisDebt = $redis->get($redisKey);
        
        if ($redisDebt !== false) {
            $negativeBalance = (float) $redisDebt;
        } else {
            // Fallback: If not in Redis, call the Payment Server Endpoint
            // TODO: Replace with the actual Payment Server Endpoint URL and API Key
            /*
            $paymentApiUrl = "https://payment.siroapp.com/api/get_debt?passenger_id=" . urlencode($passenger_id);
            $options = [
                "http" => [
                    "header" => "Authorization: Bearer YOUR_API_KEY\r\n"
                ]
            ];
            $context = stream_context_create($options);
            $response = file_get_contents($paymentApiUrl, false, $context);
            if ($response !== false) {
                $data = json_decode($response, true);
                if (isset($data['debt'])) {
                    $negativeBalance = (float) $data['debt'];
                    // Cache the result in Redis for future pricing calls (e.g. 1 hour)
                    $redis->setex($redisKey, 3600, $negativeBalance);
                }
            }
            */
        }
    } catch (Exception $e) {
        // If Redis fails, gracefully default to 0 or fallback API
        $negativeBalance = 0;
    }
}

$prices = ['total' => $withCommission];

// 4. Apply Discount and Negative Balance
foreach ($prices as $key => $price) {
    // Apply discount (Assuming percentage discount if amount <= 100, else fixed amount)
    if ($discount > 0 && $discount <= 100) {
        $prices[$key] = max(0, $price - ($price * ($discount / 100)));
    } else {
        $prices[$key] = max(0, $price - $discount);
    }
    
    // Add negative balance
    $prices[$key] += $negativeBalance;
}

echo json_encode([
    'status' => 'success',
    'data' => $prices,
    'applied_discount' => $discount,
    'added_negative_balance' => $negativeBalance
]);
?>
