<?php
declare(strict_types=1);

function hv5_verify_webhook_signature(string $token, string $providedSecret, array $payload, ?string $signatureHeader): bool {
    if ($providedSecret === '' || $token === '') return false;
    if ($signatureHeader) {
        $expected = hash_hmac('sha256', json_encode($payload), $providedSecret);
        return hash_equals($expected, $signatureHeader);
    }
    return hash_equals($providedSecret, (string)($payload['secret'] ?? ''));
}

function hv5_process_inbound_reservation(array $conn, array $payload): ?int {
    $pdo = db();
    $propertyId = (int)($payload['property_id'] ?? $conn['property_id'] ?? 0);
    $checkIn = $payload['check_in'] ?? $payload['start_date'] ?? null;
    $checkOut = $payload['check_out'] ?? $payload['end_date'] ?? null;
    if (!$propertyId || !$checkIn || !$checkOut) return null;

    $pdo->beginTransaction();
    try {
        $lock = function_exists('hv5_acquire_reservation_lock')
            ? hv5_acquire_reservation_lock($pdo, $propertyId, $checkIn, $checkOut, 'ota_inbound')
            : null;
        if ($lock === null) {
            $pdo->rollBack();
            if (function_exists('hv4_log_sync')) {
                hv4_log_sync((int)$conn['id'], 'reservation.conflict', 'conflict', 'Double booking prevented', null, $payload);
            }
            return null;
        }

        $ref = 'OTA-' . strtoupper(bin2hex(random_bytes(3)));
        $guest = v_str($payload, 'guest_name', 150) ?: 'OTA Guest';
        $total = (float)($payload['total'] ?? 0);
        $pdo->prepare('INSERT INTO bookings (reference,property_id,guest_name,check_in,check_out,nights,total,status,source) VALUES (?,?,?,?,?,?,?,?,?)')
            ->execute([
                $ref, $propertyId, $guest, $checkIn, $checkOut,
                max(1, (int)((strtotime($checkOut) - strtotime($checkIn)) / 86400)),
                $total, 'confirmed', $conn['provider'] ?? 'ota',
            ]);
        $bid = (int)$pdo->lastInsertId();
        if (function_exists('hv5_commit_reservation_lock')) hv5_commit_reservation_lock($pdo, $lock, $bid);
        if (function_exists('hv4_sync_calendar_block')) hv4_sync_calendar_block($pdo, $bid);
        if (function_exists('hv4_queue_outbound_sync')) hv4_queue_outbound_sync('calendar.block', ['booking_id' => $bid, 'property_id' => $propertyId]);
        if (function_exists('hv4_emit_event')) hv4_emit_event('booking.created', ['id' => $bid, 'source' => 'ota'], 'booking', $bid);
        $pdo->commit();
        if (hv5_table_exists('ota_health')) {
            db()->prepare('INSERT INTO ota_health (ota_connection_id, status, last_success_at, fail_count) VALUES (?,?,NOW(),0) ON DUPLICATE KEY UPDATE status="healthy", last_success_at=NOW(), fail_count=0')
                ->execute([(int)$conn['id'], 'healthy']);
        }
        return $bid;
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
    }
}

function hv5_ota_health_snapshot(): array {
    if (!hv5_table_exists('ota_health')) return [];
    return db()->query('SELECT h.*, c.name, c.provider FROM ota_health h JOIN ota_connections c ON c.id=h.ota_connection_id')->fetchAll() ?: [];
}
