<?php

declare(strict_types=1);

namespace App\Application\GraphQL;

use App\Framework\GraphQL\Subscriptions\SubscriptionManager;

/**
 * Service for publishing notifications to GraphQL subscribers
 *
 * Example usage:
 *
 * $publisher->publishNotification('user-123', [
 *     'id' => 'notif-456',
 *     'message' => 'Your order has been shipped',
 *     'type' => 'order_update',
 *     'createdAt' => time()
 * ]);
 */
final readonly class NotificationPublisher
{
    public function __construct(
        private SubscriptionManager $subscriptionManager
    ) {
    }

    /**
     * Publish a notification to a specific user
     *
     * @return int Number of subscribers notified
     */
    public function publishNotification(string $userId, array $notification): int
    {
        return $this->subscriptionManager->publish(
            subscriptionName: 'notificationReceived',
            payload: $notification,
            filter: fn (array $variables, array $payload) => $variables['userId'] === $userId
        );
    }

    /**
     * Publish order status change to subscribers
     *
     * @return int Number of subscribers notified
     */
    public function publishOrderStatusChange(string $orderId, string $status, ?string $estimatedDelivery = null): int
    {
        $payload = [
            'orderId' => $orderId,
            'status' => $status,
            'updatedAt' => date('Y-m-d H:i:s'),
            'estimatedDelivery' => $estimatedDelivery,
        ];

        return $this->subscriptionManager->publish(
            subscriptionName: 'orderStatusChanged',
            payload: $payload,
            filter: fn (array $variables, array $payload) => $variables['orderId'] === $orderId
        );
    }

    /**
     * Publish system-wide announcement to all subscribers
     *
     * @return int Number of subscribers notified
     */
    public function publishSystemAnnouncement(string $title, string $message, string $priority = 'normal'): int
    {
        $payload = [
            'title' => $title,
            'message' => $message,
            'priority' => $priority,
            'timestamp' => time(),
        ];

        return $this->subscriptionManager->publish(
            subscriptionName: 'systemAnnouncement',
            payload: $payload
            // No filter - send to all subscribers
        );
    }
}
