<?php
session_start();
header('Content-Type: application/json');

require_once __DIR__ . '/vendor/autoload.php';

use App\Core\Database;
use App\Services\MailService;

$response = [
    'status' => 'error',
    'message' => 'Invalid request.'
];

try {

    // ======================================================
    // CSRF VALIDATION
    // ======================================================
    if (
        empty($_POST['csrf_token']) ||
        $_POST['csrf_token'] !== $_SESSION['csrf_token']
    ) {
        throw new Exception('Invalid security token.');
    }

    $db = Database::connect();
    $db->beginTransaction();

    // ======================================================
    // SANITIZE INPUT
    // ======================================================
    $service_id      = (int) ($_POST['service_id'] ?? 0);
    $zone_id         = (int) ($_POST['zone_id'] ?? 0);
    $vehicle_type    = trim($_POST['vehicle_type'] ?? '');
    $hours           = (int) ($_POST['hours'] ?? 0);

    $pickup_address  = trim($_POST['pickup_address'] ?? '');
    $dropoff_address = trim($_POST['dropoff_address'] ?? '');
    $flight_number   = trim($_POST['flight_number'] ?? '');

    $pickup_datetime = $_POST['pickup_datetime'] ?? null;

    $name  = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $phone = trim($_POST['phone'] ?? '');

    if (
        !$service_id ||
        !$vehicle_type ||
        !$pickup_address ||
        !$pickup_datetime ||
        !$name ||
        !$email
    ) {
        throw new Exception('Missing required fields.');
    }

    // ======================================================
    // FETCH PRICE RULE
    // ======================================================
    $stmt = $db->prepare("
        SELECT pr.*, s.service_name
        FROM price_rules pr
        JOIN services s ON s.id = pr.service_id
        WHERE pr.service_id = ? AND pr.is_active = 1
        LIMIT 1
    ");
    $stmt->execute([$service_id]);
    $rule = $stmt->fetch();

    if (!$rule) {
        throw new Exception('Pricing rule not found.');
    }

    $pricing_type            = $rule['pricing_type'];
    $base_price              = (float) $rule['base_price'];
    $hourly_rate             = (float) $rule['hourly_rate'];
    $minimum_hours           = (int) $rule['minimum_hours'];
    $zone_required           = (int) $rule['zone_required'];
    $airport_pickup_default  = (int) $rule['airport_pickup_default'];
    $airport_dropoff_default = (int) $rule['airport_dropoff_default'];
    $flight_required         = (int) $rule['flight_required'];

    // ======================================================
    // AIRPORT RULES (DB DRIVEN)
    // ======================================================
    if ($airport_pickup_default === 1) {
        $pickup_address = "Changi Airport";
    }

    if ($airport_dropoff_default === 1) {
        $dropoff_address = "Changi Airport";
    }

    if ($flight_required === 1 && empty($flight_number)) {
        throw new Exception('Flight number is required for this service.');
    }

    // ======================================================
    // PRICE CALCULATION (100% DB DRIVEN)
    // ======================================================
    $final_price = 0;

    // FIXED
    if ($pricing_type === 'fixed') {
        $final_price = $base_price;
    }

    // ZONE
    elseif ($pricing_type === 'zone') {

        if ($zone_required === 1 && !$zone_id) {
            throw new Exception('Pickup zone is required.');
        }

        $stmt = $db->prepare("SELECT price_modifier FROM zones WHERE id = ?");
        $stmt->execute([$zone_id]);
        $zone = $stmt->fetch();

        if (!$zone) {
            throw new Exception('Invalid zone selected.');
        }

        $final_price = (float) $zone['price_modifier'];
    }

    // HOURLY
    elseif ($pricing_type === 'hourly') {

        if ($hours < $minimum_hours) {
            throw new Exception("Minimum booking is {$minimum_hours} hours.");
        }

        $final_price = $hourly_rate * $hours;
    }

    if ($final_price <= 0) {
        throw new Exception('Unable to calculate price.');
    }

    // ======================================================
    // FIND OR CREATE CUSTOMER
    // ======================================================
    $stmt = $db->prepare("SELECT id FROM customers WHERE email = ? LIMIT 1");
    $stmt->execute([$email]);
    $customer = $stmt->fetch();

    if ($customer) {
        $customer_id = $customer['id'];
    } else {
        $stmt = $db->prepare("
            INSERT INTO customers (name, email, phone)
            VALUES (?, ?, ?)
        ");
        $stmt->execute([$name, $email, $phone]);
        $customer_id = $db->lastInsertId();
    }

    // ======================================================
    // GENERATE BOOKING REFERENCE
    // ======================================================
    do {
        $booking_reference = 'EXC' . date('Ymd') . random_int(1000, 9999);
        $check = $db->prepare("SELECT id FROM bookings WHERE booking_reference = ?");
        $check->execute([$booking_reference]);
    } while ($check->fetch());

    // ======================================================
    // INSERT BOOKING
    // ======================================================
    $stmt = $db->prepare("
        INSERT INTO bookings (
            booking_reference,
            customer_id,
            service_id,
            zone_id,
            vehicle_type,
            pickup_address,
            dropoff_address,
            flight_number,
            pickup_datetime,
            hours,
            estimated_price,
            final_price,
            status
        )
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
    ");

    $stmt->execute([
        $booking_reference,
        $customer_id,
        $service_id,
        $zone_id ?: null,
        $vehicle_type,
        $pickup_address,
        $dropoff_address,
        $flight_number ?: null,
        $pickup_datetime,
        $hours ?: null,
        $final_price,
        $final_price
    ]);

    $booking_id = $db->lastInsertId();

    // ======================================================
    // INSERT BOOKING TIMELINE
    // ======================================================
    $stmt = $db->prepare("
        INSERT INTO booking_timeline (booking_id, status, updated_by)
        VALUES (?, 'pending', 'system')
    ");
    $stmt->execute([$booking_id]);

    // ======================================================
    // COMMIT
    // ======================================================
    $db->commit();

    // Regenerate CSRF (prevent replay)
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));

    $response = [
        'status' => 'success',
        'redirect' => 'booking_success.php?ref=' . $booking_reference
    ];

} catch (Exception $e) {

    if (isset($db) && $db->inTransaction()) {
        $db->rollBack();
    }

    $response = [
        'status' => 'error',
        'message' => $e->getMessage()
    ];
}

echo json_encode($response);
