<?php

declare(strict_types=1);

namespace Drupal\flowdrop_session\EventSubscriber;

use Drupal\flowdrop_runtime\Service\RealTime\RealTimeManagerInterface;
use Drupal\flowdrop_session\Event\SessionTurnCompletedEvent;
use Drupal\flowdrop_session\Event\SessionTurnStartedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Bridges the session turn domain events onto the RealTime channel.
 *
 * Forwards SessionTurnStarted/Completed to RealTimeManager as
 * session-keyed broadcasts, so one subscription point
 * (RealTimeBroadcastEvent) carries node status, pipeline status, AND
 * turn lifecycle — all keyed. Payload shapes are part of the documented
 * contract (docs/reference/api/session-turn-events.md); evolution is
 * additive-only.
 *
 * @internal The subscriber is internal; the broadcast payload is not.
 */
final class SessionTurnRealTimeSubscriber implements EventSubscriberInterface {

  public function __construct(
    private readonly RealTimeManagerInterface $realTimeManager,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    return [
      SessionTurnStartedEvent::NAME => 'onTurnStarted',
      SessionTurnCompletedEvent::NAME => 'onTurnCompleted',
    ];
  }

  /**
   * Broadcasts a 'turn_started' session event.
   */
  public function onTurnStarted(SessionTurnStartedEvent $event): void {
    $this->realTimeManager->broadcastSessionEvent($event->sessionId, 'turn_started', [
      'turn_id' => $event->turnId,
      'pipeline_id' => $event->pipelineId,
      'workflow_id' => $event->workflowId,
    ]);
  }

  /**
   * Broadcasts a 'turn_completed' session event.
   */
  public function onTurnCompleted(SessionTurnCompletedEvent $event): void {
    $this->realTimeManager->broadcastSessionEvent($event->sessionId, 'turn_completed', [
      'turn_id' => $event->turnId,
      'pipeline_id' => $event->pipelineId,
      'status' => $event->status,
      'assistant_message_ids' => $event->assistantMessageIds,
      'paused_reason' => $event->pausedReason,
    ]);
  }

}
