<?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;
}

$prices = [];
$pricesRaw = [];

$categories = [
    'totalPassengerSpeed' => 'Speed',
    'totalPassengerBalash' => 'Awfar Car',
    'totalPassengerComfort' => 'Comfort',
    'totalPassengerElectric' => 'Electric',
    'totalPassengerLady' => 'Lady',
    'totalPassengerScooter' => 'Delivery',
    'totalPassengerVan' => 'Van',
    'totalPassengerRayehGai' => 'Speed',
    'totalPassengerRayehGaiComfort' => 'Comfort',
    'totalPassengerRayehGaiBalash' => 'Awfar Car',
];

// 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;
}

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

function getPerKmRate($carType, $kazanRow) {
    $rateColumns = [
        'Comfort'     => 'comfortPrice',
        'Speed'       => 'speedPrice',
        'Lady'        => 'ladyPrice',
        'Electric'    => 'electricPrice',
        'Van'         => 'vanPrice',
        'Delivery'    => 'deliveryPrice',
        'Mishwar Vip' => 'mishwarVipPrice',
        'Fixed Price' => 'fixedPrice',
        'Awfar Car'   => 'awfarPrice',
    ];

    $column = $rateColumns[$carType] ?? 'speedPrice';
    $rate = floatval($kazanRow[$column] ?? 0);
    
    if ($rate <= 0) {
        $oldColumnMap = [
            'Lady'        => 'familyPrice',
            'Mishwar Vip' => 'freePrice',
            'Electric'    => 'naturePrice',
            'Van'         => 'heavyPrice',
        ];
        $oldColumn = $oldColumnMap[$carType] ?? null;
        if ($oldColumn && isset($kazanRow[$oldColumn])) {
            $rate = floatval($kazanRow[$oldColumn]);
        }
    }
    
    if ($rate <= 0) {
        $rate = floatval($kazanRow['speedPrice'] ?? 36);
    }
    
    return $rate;
}

function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType = 'Speed') {
    $naturePrice = (float) ($kazanRow['naturePrice'] ?? 0);
    $heavyPrice = (float) ($kazanRow['heavyPrice'] ?? 0);
    $latePrice = (float) ($kazanRow['latePrice'] ?? 0);
    $kazanPercent = (float) ($kazanRow['kazan'] ?? 10);
    
    // === 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 = getPerKmRate($carType, $kazanRow);
    $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)
$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;
        }
    } catch (Exception $e) {
        $negativeBalance = 0;
    }
}

// Calculate prices for all categories
foreach ($categories as $key => $carType) {
    $result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType);
    $withCommission = $result['withCommission'];
    $price_for_driver = $result['price_for_driver'];

    // Apply discount
    if ($discount > 0 && $discount <= 100) {
        $finalPrice = max(0, $withCommission - ($withCommission * ($discount / 100)));
    } else {
        $finalPrice = max(0, $withCommission - $discount);
    }
    
    // Add negative balance
    $finalPrice += $negativeBalance;
    
    $prices[$key] = $finalPrice;
    
    // For the token, we map the clean database carType to the final price and driver price
    $pricesRaw[$carType] = [
        'price' => $finalPrice,
        'driver_price' => $price_for_driver
    ];
}

// 4. Generate Cryptographically Signed Token
$priceToken = "";
if (isset($encryptionHelper)) {
    $tokenPayload = [
        'passenger_id'   => $passenger_id,
        'start_location' => $passengerLat . ',' . $passengerLng,
        'end_location'   => $destLat . ',' . $destLng,
        // ✅ FIX R6: تضمين distance و duration في الـ token لمنع التلاعب
        'distance'       => $distance,
        'duration'       => $duration,
        'expires'        => time() + 180, // Valid for 3 minutes
        'prices'         => $pricesRaw
    ];
    $priceToken = $encryptionHelper->encryptData(json_encode($tokenPayload));
}

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