<?php

declare(strict_types=1);

namespace App\Service;

use Psr\Log\LoggerInterface;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;

/**
 * Thin wrapper around the Mercure hub for device-state pushes.
 *
 * Topic shape: `https://wevisto.com/devices/{id}` — same convention
 * aqua-iq uses. The browser subscribes per device id; the published payload is
 * the same JSON the REST API would have returned, so the SPA can splat it
 * straight into the device store with no separate envelope handling.
 *
 * Errors are swallowed and logged — a flaky hub must never break a poll
 * response or a settings PATCH for the user.
 */
final class MercurePublisher
{
    public const TOPIC_PREFIX = 'https://wevisto.com/devices/';

    public function __construct(
        private readonly HubInterface    $hub,
        private readonly LoggerInterface $logger,
    ) {}

    public function publishDevice(int $deviceId, array $payload): void
    {
        try {
            $this->hub->publish(new Update(
                self::TOPIC_PREFIX . $deviceId,
                json_encode($payload, JSON_THROW_ON_ERROR),
            ));
        } catch (\Throwable $e) {
            $this->logger->warning('mercure.publish_failed', [
                'device_id' => $deviceId,
                'error'     => $e->getMessage(),
            ]);
        }
    }
}
