<?php
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Create Reservation from Channel Import';

if (!function_exists('h')) {
    function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('money_fmt')) {
    function money_fmt($amount): string { return number_format((float)$amount, 2); }
}
if (!function_exists('ccr_table_exists')) {
    function ccr_table_exists(PDO $pdo, string $tableName): bool {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM information_schema.tables
            WHERE table_schema = DATABASE()
              AND table_name = :table_name
        ");
        $stmt->execute([':table_name' => $tableName]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('ccr_column_exists')) {
    function ccr_column_exists(PDO $pdo, string $tableName, string $columnName): bool {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM information_schema.columns
            WHERE table_schema = DATABASE()
              AND table_name = :table_name
              AND column_name = :column_name
        ");
        $stmt->execute([':table_name' => $tableName, ':column_name' => $columnName]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('ccr_flash')) {
    function ccr_flash(string $type, string $message): void {
        $_SESSION['channel_create_reservation_flash'][] = ['type' => $type, 'message' => $message];
    }
}
if (!function_exists('ccr_get_flash')) {
    function ccr_get_flash(): array {
        $items = $_SESSION['channel_create_reservation_flash'] ?? [];
        unset($_SESSION['channel_create_reservation_flash']);
        return $items;
    }
}
if (!function_exists('ccr_pretty_json')) {
    function ccr_pretty_json(?string $value): string {
        $value = (string)$value;
        if (trim($value) === '') return '';
        $decoded = json_decode($value, true);
        if (json_last_error() === JSON_ERROR_NONE) {
            return json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
        }
        return $value;
    }
}
if (!function_exists('ccr_first_value')) {
    function ccr_first_value(array $data, array $keys, $default = '') {
        foreach ($keys as $key) {
            if (isset($data[$key]) && trim((string)$data[$key]) !== '') {
                return $data[$key];
            }
        }
        return $default;
    }
}
if (!function_exists('ccr_insert_flexible')) {
    function ccr_insert_flexible(PDO $pdo, string $table, array $data): int {
        $cols = [];
        $params = [];
        $values = [];

        foreach ($data as $col => $value) {
            if (ccr_column_exists($pdo, $table, $col)) {
                $cols[] = "`$col`";
                $param = ':' . $col;
                $params[] = $param;
                $values[$param] = $value;
            }
        }

        if (!$cols) {
            throw new RuntimeException("No matching insert columns found for {$table}.");
        }

        $sql = "INSERT INTO `$table` (" . implode(',', $cols) . ") VALUES (" . implode(',', $params) . ")";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($values);

        return (int)$pdo->lastInsertId();
    }
}
if (!function_exists('ccr_update_flexible')) {
    function ccr_update_flexible(PDO $pdo, string $table, array $data, string $pk, int $id): void {
        $sets = [];
        $values = [':pk_id' => $id];

        foreach ($data as $col => $value) {
            if (ccr_column_exists($pdo, $table, $col)) {
                $sets[] = "`$col` = :$col";
                $values[':' . $col] = $value;
            }
        }

        if (!$sets) return;

        $sql = "UPDATE `$table` SET " . implode(',', $sets) . " WHERE `$pk` = :pk_id";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($values);
    }
}
if (!function_exists('ccr_find_or_create_guest')) {
    function ccr_find_or_create_guest(PDO $pdo, array $booking): int {
        if (!ccr_table_exists($pdo, 'guests')) {
            return 0;
        }

        $guestName = trim((string)ccr_first_value($booking, ['guest_name', 'name'], 'OTA Guest'));
        $email = trim((string)ccr_first_value($booking, ['guest_email', 'email'], ''));
        $phone = trim((string)ccr_first_value($booking, ['guest_phone', 'phone', 'mobile'], ''));

        if ($email !== '' && ccr_column_exists($pdo, 'guests', 'email')) {
            $stmt = $pdo->prepare("SELECT id FROM guests WHERE email = :email LIMIT 1");
            $stmt->execute([':email' => $email]);
            $existing = $stmt->fetchColumn();
            if ($existing) return (int)$existing;
        }

        $parts = preg_split('/\s+/', $guestName, 2);
        $firstName = $parts[0] ?? 'OTA';
        $lastName = $parts[1] ?? 'Guest';

        return ccr_insert_flexible($pdo, 'guests', [
            'firstname' => $firstName,
            'lastname' => $lastName,
            'name' => $guestName,
            'guest_name' => $guestName,
            'email' => $email,
            'phone' => $phone,
            'mobile' => $phone,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
    }
}
if (!function_exists('ccr_generate_order_no')) {
    function ccr_generate_order_no(PDO $pdo): string {
        $prefix = 'OTA-' . date('ymd') . '-';
        $next = 1;

        if (ccr_table_exists($pdo, 'orders') && ccr_column_exists($pdo, 'orders', 'order_no')) {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE order_no LIKE :prefix");
            $stmt->execute([':prefix' => $prefix . '%']);
            $next += (int)$stmt->fetchColumn();
        }

        return $prefix . str_pad((string)$next, 4, '0', STR_PAD_LEFT);
    }
}
if (!function_exists('ccr_match_room_type')) {
    function ccr_match_room_type(PDO $pdo, int $connectionId, array $booking): ?array {
        $externalRoomId = trim((string)ccr_first_value($booking, ['room_type_external_id', 'external_room_id', 'room_id'], ''));

        if ($externalRoomId === '') {
            return null;
        }

        $stmt = $pdo->prepare("
            SELECT
                crm.*,
                rt.title AS room_type,
                rt.property_id AS room_type_property_id
            FROM channel_room_mapping crm
            INNER JOIN room_types rt ON rt.id = crm.room_type_id
            WHERE crm.connection_id = :connection_id
              AND crm.external_room_id = :external_room_id
              AND crm.is_active = 1
            LIMIT 1
        ");
        $stmt->execute([
            ':connection_id' => $connectionId,
            ':external_room_id' => $externalRoomId,
        ]);

        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ?: null;
    }
}
if (!function_exists('ccr_find_available_room')) {
    function ccr_find_available_room(PDO $pdo, int $roomTypeId, int $propertyId, string $checkIn, string $checkOut): int {
        if (!ccr_table_exists($pdo, 'rooms')) return 0;

        $hasRoomActive = ccr_column_exists($pdo, 'rooms', 'is_active');
        $hasRoomStatus = ccr_column_exists($pdo, 'rooms', 'status');

        $where = "r.room_type_id = :room_type_id";
        $params = [':room_type_id' => $roomTypeId];

        if ($propertyId > 0) {
            $where .= " AND COALESCE(r.property_id, rt.property_id) = :property_id";
            $params[':property_id'] = $propertyId;
        }

        if ($hasRoomActive) $where .= " AND COALESCE(r.is_active, 1) = 1";
        if ($hasRoomStatus) $where .= " AND (r.status IS NULL OR r.status NOT IN ('inactive','out_of_order','blocked'))";

        $stmt = $pdo->prepare("
            SELECT r.id
            FROM rooms r
            LEFT JOIN room_types rt ON rt.id = r.room_type_id
            WHERE $where
              AND NOT EXISTS (
                  SELECT 1
                  FROM order_rooming orm
                  WHERE orm.room_id = r.id
                    AND orm.check_in < :check_out
                    AND orm.check_out > :check_in
                    " . (ccr_column_exists($pdo, 'order_rooming', 'cancelled') ? "AND COALESCE(orm.cancelled,0)=0" : "") . "
              )
            ORDER BY r.room_no ASC, r.id ASC
            LIMIT 1
        ");
        $params[':check_in'] = $checkIn;
        $params[':check_out'] = $checkOut;
        $stmt->execute($params);

        return (int)($stmt->fetchColumn() ?: 0);
    }
}
if (!function_exists('ccr_create_order')) {
    function ccr_create_order(PDO $pdo, array $import, array $booking, array $connection, int $guestId, int $roomTypeId, int $roomId): int {
        $checkIn = (string)($import['check_in'] ?: ccr_first_value($booking, ['check_in'], date('Y-m-d')));
        $checkOut = (string)($import['check_out'] ?: ccr_first_value($booking, ['check_out'], date('Y-m-d', strtotime('+1 day'))));
        $total = (float)($import['total_amount'] ?? ccr_first_value($booking, ['total_amount'], 0));
        $orderNo = ccr_generate_order_no($pdo);
        $guestName = trim((string)($import['guest_name'] ?: ccr_first_value($booking, ['guest_name'], 'OTA Guest')));
        $propertyId = (int)($connection['property_id'] ?? 0);
        $adults = (int)ccr_first_value($booking, ['adults'], 1);
        $children = (int)ccr_first_value($booking, ['children'], 0);
        $notes = 'Imported from ' . ($connection['provider'] ?? 'channel') . '. External booking ID: ' . ($import['external_booking_id'] ?? '');

        $orderId = ccr_insert_flexible($pdo, 'orders', [
            'order_no' => $orderNo,
            'property_id' => $propertyId ?: null,
            'guest_id' => $guestId ?: null,
            'guest_name' => $guestName,
            'pax_name' => $guestName,
            'check_in' => $checkIn,
            'check_out' => $checkOut,
            'arrival_date' => $checkIn,
            'departure_date' => $checkOut,
            'status' => 'confirmed',
            'booking_status' => 'confirmed',
            'source' => 'channel',
            'channel' => $connection['provider'] ?? 'channel',
            'external_booking_id' => $import['external_booking_id'] ?? null,
            'total_amount' => $total,
            'amount' => $total,
            'grand_total' => $total,
            'adults' => $adults,
            'children' => $children,
            'notes' => $notes,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);

        ccr_insert_flexible($pdo, 'order_rooming', [
            'order_id' => $orderId,
            'property_id' => $propertyId ?: null,
            'room_type_id' => $roomTypeId,
            'room_id' => $roomId ?: null,
            'room_no' => null,
            'check_in' => $checkIn,
            'check_out' => $checkOut,
            'adults' => $adults,
            'children' => $children,
            'rate' => $total > 0 ? $total / max(1, (int)((strtotime($checkOut) - strtotime($checkIn)) / 86400)) : 0,
            'amount' => $total,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);

        if (ccr_table_exists($pdo, 'folios')) {
            $folioNo = 'F-' . str_pad((string)$orderId, 6, '0', STR_PAD_LEFT);
            ccr_insert_flexible($pdo, 'folios', [
                'order_id' => $orderId,
                'folio_no' => $folioNo,
                'folio_name' => 'Master Folio',
                'status' => 'open',
                'total_charges' => $total,
                'total_payments' => 0,
                'balance' => $total,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }

        return $orderId;
    }
}

$errors = [];

foreach (['channel_booking_imports', 'channel_connections', 'orders', 'order_rooming'] as $table) {
    if (!ccr_table_exists($pdo, $table)) {
        $errors[] = 'Required table missing: ' . $table;
    }
}

$importId = (int)($_GET['import_id'] ?? $_POST['import_id'] ?? 0);
$import = null;
$connection = null;
$booking = [];
$roomMapping = null;
$availableRoomId = 0;

if ($importId <= 0) {
    $errors[] = 'No import ID supplied.';
}

if (!$errors) {
    try {
        $stmt = $pdo->prepare("
            SELECT
                cbi.*,
                cc.provider,
                cc.connection_name,
                cc.property_id,
                cc.external_property_id,
                p.name AS property_name,
                p.code AS property_code
            FROM channel_booking_imports cbi
            INNER JOIN channel_connections cc ON cc.id = cbi.connection_id
            LEFT JOIN properties p ON p.id = cc.property_id
            WHERE cbi.id = :id
            LIMIT 1
        ");
        $stmt->execute([':id' => $importId]);
        $import = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$import) {
            throw new RuntimeException('Import queue item not found.');
        }

        $connection = [
            'id' => (int)$import['connection_id'],
            'provider' => $import['provider'],
            'connection_name' => $import['connection_name'],
            'property_id' => (int)$import['property_id'],
            'external_property_id' => $import['external_property_id'],
        ];

        $booking = json_decode((string)$import['raw_payload'], true);
        if (!is_array($booking)) {
            $booking = [];
        }

        $roomMapping = ccr_match_room_type($pdo, (int)$import['connection_id'], $booking);

        if ($roomMapping) {
            $propertyId = (int)($roomMapping['property_id'] ?: $connection['property_id']);
            $availableRoomId = ccr_find_available_room(
                $pdo,
                (int)$roomMapping['room_type_id'],
                $propertyId,
                (string)$import['check_in'],
                (string)$import['check_out']
            );
        }

    } catch (Throwable $e) {
        $errors[] = $e->getMessage();
    }
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    try {
        if (function_exists('verify_csrf')) verify_csrf();

        if (!$import) throw new RuntimeException('Import not loaded.');
        if (!empty($import['order_id'])) throw new RuntimeException('This import is already linked to a PMS reservation.');
        if (!$roomMapping) throw new RuntimeException('Could not match external room ID to a PMS room type. Please configure Channel Mapping first.');

        $roomTypeId = (int)$roomMapping['room_type_id'];
        $propertyId = (int)($roomMapping['property_id'] ?: $connection['property_id']);
        $selectedRoomId = (int)($_POST['room_id'] ?? 0);
        $allowUnassigned = isset($_POST['allow_unassigned']) ? 1 : 0;

        if ($selectedRoomId <= 0) {
            $selectedRoomId = $availableRoomId;
        }

        if ($selectedRoomId <= 0 && !$allowUnassigned) {
            throw new RuntimeException('No available physical room found. Tick allow unassigned to create the booking without a room.');
        }

        $pdo->beginTransaction();

        $guestId = ccr_find_or_create_guest($pdo, $booking);
        $orderId = ccr_create_order($pdo, $import, $booking, $connection, $guestId, $roomTypeId, $selectedRoomId);

        ccr_update_flexible($pdo, 'channel_booking_imports', [
            'order_id' => $orderId,
            'import_status' => 'imported',
            'imported_at' => date('Y-m-d H:i:s'),
        ], 'id', $importId);

        if (ccr_table_exists($pdo, 'channel_sync_log')) {
            $stmt = $pdo->prepare("
                INSERT INTO channel_sync_log
                (connection_id, provider, sync_type, sync_direction, status, request_payload, response_payload, message, started_at, completed_at)
                VALUES
                (:connection_id, :provider, 'create_reservation', 'pull', 'success', :request_payload, :response_payload, :message, NOW(), NOW())
            ");
            $stmt->execute([
                ':connection_id' => (int)$import['connection_id'],
                ':provider' => (string)$import['provider'],
                ':request_payload' => json_encode(['import_id' => $importId, 'external_booking_id' => $import['external_booking_id']], JSON_PRETTY_PRINT),
                ':response_payload' => json_encode(['order_id' => $orderId, 'guest_id' => $guestId, 'room_id' => $selectedRoomId], JSON_PRETTY_PRINT),
                ':message' => 'Channel import converted to PMS reservation.',
            ]);
        }

        $pdo->commit();

        ccr_flash('success', 'Reservation created successfully from channel import.');
        header('Location: /rooms/modules/reservations/reservation_view.php?order_id=' . (int)$orderId);
        exit;

    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        ccr_flash('danger', $e->getMessage());
        header('Location: channel_create_reservation.php?import_id=' . $importId);
        exit;
    }
}

$rooms = [];
if ($roomMapping && ccr_table_exists($pdo, 'rooms')) {
    try {
        $propertyId = (int)($roomMapping['property_id'] ?: $connection['property_id']);
        $where = "r.room_type_id = :room_type_id";
        $params = [':room_type_id' => (int)$roomMapping['room_type_id']];

        if ($propertyId > 0) {
            $where .= " AND COALESCE(r.property_id, rt.property_id) = :property_id";
            $params[':property_id'] = $propertyId;
        }

        $stmt = $pdo->prepare("
            SELECT r.id, r.room_no
            FROM rooms r
            LEFT JOIN room_types rt ON rt.id = r.room_type_id
            WHERE $where
            ORDER BY r.room_no ASC, r.id ASC
        ");
        $stmt->execute($params);
        $rooms = $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (Throwable $e) {
        $rooms = [];
    }
}

$flashes = ccr_get_flash();

require_once __DIR__ . '/../../includes/header.php';
?>

<div class="hero-band">
    <div class="row g-4 align-items-center">
        <div class="col-lg-8">
            <div class="page-eyebrow text-white-50"><i class="bi bi-plus-circle"></i> Channel Manager</div>
            <div class="hero-title mt-2">Create Reservation from Channel Import</div>
            <div class="hero-subtitle mt-2">
                Convert an imported OTA booking into a PMS reservation after checking room mappings and availability.
            </div>
        </div>
        <div class="col-lg-4 text-lg-end">
            <a href="channel_pull_bookings.php" class="btn btn-light me-2">
                <i class="bi bi-cloud-download me-2"></i>Pull Bookings
            </a>
            <a href="channel_sync_log.php" class="btn btn-outline-light">
                <i class="bi bi-clock-history me-2"></i>Sync Log
            </a>
        </div>
    </div>
</div>

<?php foreach ($flashes as $flash): ?>
    <div class="alert alert-<?php echo h($flash['type']); ?>"><?php echo h($flash['message']); ?></div>
<?php endforeach; ?>

<?php if ($errors): ?>
    <div class="alert alert-danger">
        <div class="fw-bold mb-2">Please fix the following:</div>
        <ul class="mb-0">
            <?php foreach ($errors as $err): ?><li><?php echo h($err); ?></li><?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<?php if ($import): ?>
<div class="row g-4">
    <div class="col-xl-8">
        <div class="card panel-card mb-4">
            <div class="card-header"><h5 class="mb-0">Imported Booking</h5></div>
            <div class="card-body">
                <div class="row g-3">
                    <div class="col-md-4">
                        <div class="detail-label">External Booking ID</div>
                        <div class="detail-value"><?php echo h($import['external_booking_id']); ?></div>
                    </div>
                    <div class="col-md-4">
                        <div class="detail-label">Provider</div>
                        <div class="detail-value"><?php echo h(ucwords(str_replace('_', ' ', $import['provider']))); ?></div>
                    </div>
                    <div class="col-md-4">
                        <div class="detail-label">Connection</div>
                        <div class="detail-value"><?php echo h($import['connection_name']); ?></div>
                    </div>
                    <div class="col-md-4">
                        <div class="detail-label">Guest</div>
                        <div class="detail-value"><?php echo h($import['guest_name'] ?: ccr_first_value($booking, ['guest_name'], 'OTA Guest')); ?></div>
                    </div>
                    <div class="col-md-4">
                        <div class="detail-label">Stay</div>
                        <div class="detail-value"><?php echo h($import['check_in']); ?> → <?php echo h($import['check_out']); ?></div>
                    </div>
                    <div class="col-md-4">
                        <div class="detail-label">Amount</div>
                        <div class="detail-value"><?php echo h($import['currency'] ?: 'USD'); ?> <?php echo money_fmt($import['total_amount']); ?></div>
                    </div>
                </div>

                <?php if (!empty($import['order_id'])): ?>
                    <div class="alert alert-success mt-4 mb-0">
                        This import is already linked to PMS reservation
                        <a href="/rooms/modules/reservations/reservation_view.php?order_id=<?php echo (int)$import['order_id']; ?>">
                            #<?php echo (int)$import['order_id']; ?>
                        </a>.
                    </div>
                <?php endif; ?>
            </div>
        </div>

        <div class="card panel-card mb-4">
            <div class="card-header"><h5 class="mb-0">Mapping & Availability Check</h5></div>
            <div class="card-body">
                <?php if ($roomMapping): ?>
                    <div class="alert alert-success">
                        Matched external room ID
                        <strong><?php echo h(ccr_first_value($booking, ['room_type_external_id', 'external_room_id', 'room_id'], '')); ?></strong>
                        to PMS room type <strong><?php echo h($roomMapping['room_type']); ?></strong>.
                    </div>
                <?php else: ?>
                    <div class="alert alert-danger">
                        No PMS room type mapping found for external room ID
                        <strong><?php echo h(ccr_first_value($booking, ['room_type_external_id', 'external_room_id', 'room_id'], 'missing')); ?></strong>.
                        Please update <a href="channel_mapping.php?connection_id=<?php echo (int)$import['connection_id']; ?>">Channel Mapping</a>.
                    </div>
                <?php endif; ?>

                <?php if ($roomMapping): ?>
                    <?php if ($availableRoomId > 0): ?>
                        <div class="alert alert-info mb-0">
                            Available room found and preselected. You may override it below.
                        </div>
                    <?php else: ?>
                        <div class="alert alert-warning mb-0">
                            No available physical room found for the date range. You can still create as unassigned if your workflow allows it.
                        </div>
                    <?php endif; ?>
                <?php endif; ?>
            </div>
        </div>

        <div class="card panel-card">
            <div class="card-header"><h5 class="mb-0">Raw OTA Payload</h5></div>
            <div class="card-body">
                <pre class="payload-box"><?php echo h(ccr_pretty_json($import['raw_payload'])); ?></pre>
            </div>
        </div>
    </div>

    <div class="col-xl-4">
        <div class="card panel-card">
            <div class="card-header"><h5 class="mb-0">Create PMS Reservation</h5></div>
            <div class="card-body">
                <form method="post" onsubmit="return confirm('Create PMS reservation from this imported booking?');">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="import_id" value="<?php echo (int)$importId; ?>">

                    <div class="mb-3">
                        <label class="form-label">Room Assignment</label>
                        <select name="room_id" class="form-select" <?php echo !$roomMapping ? 'disabled' : ''; ?>>
                            <option value="0">Unassigned</option>
                            <?php foreach ($rooms as $room): ?>
                                <option value="<?php echo (int)$room['id']; ?>" <?php echo $availableRoomId === (int)$room['id'] ? 'selected' : ''; ?>>
                                    <?php echo h($room['room_no'] ?: ('Room #' . (int)$room['id'])); ?>
                                    <?php echo $availableRoomId === (int)$room['id'] ? ' - Available' : ''; ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>

                    <label class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" name="allow_unassigned" value="1" <?php echo $availableRoomId <= 0 ? 'checked' : ''; ?>>
                        <span class="form-check-label">Allow unassigned reservation</span>
                    </label>

                    <div class="alert alert-info small">
                        This will create:
                        <ul class="mb-0">
                            <li>Guest record where possible</li>
                            <li>Order / reservation</li>
                            <li>Order rooming line</li>
                            <li>Master folio if your table exists</li>
                            <li>Import queue link to PMS order</li>
                        </ul>
                    </div>

                    <button class="btn btn-primary w-100" <?php echo (!$roomMapping || !empty($import['order_id'])) ? 'disabled' : ''; ?>>
                        <i class="bi bi-plus-circle me-2"></i>Create Reservation
                    </button>
                </form>
            </div>
        </div>

        <div class="card panel-card mt-4">
            <div class="card-header"><h5 class="mb-0">Important</h5></div>
            <div class="card-body small text-muted">
                This file uses flexible column detection because PMS schemas vary. If your `orders` table uses mandatory columns not included here, MySQL will show the exact missing field and we can add it cleanly.
            </div>
        </div>
    </div>
</div>
<?php endif; ?>

<style>
.detail-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.06em;color:#64748b;font-weight:800}
.detail-value{font-weight:900;color:#111827}
.payload-box{background:#0f172a;color:#e5e7eb;border-radius:16px;padding:14px;max-height:520px;overflow:auto;font-size:12px}
</style>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
