<?php
/**
 * @package messenger
 * @author kputyr
 * @date 2026-02-03
 */

namespace IMATHUZH\Qfq\Core\Messenger;

/**
 * Publishes chat events to nchan via the existing Messenger endpoint.
 *
 * Uses the MessageDispatcher and HttpPublisher to send notifications
 * when chat messages are saved or toolbar state changes (tags/done).
 */
class ChatPublisher {
    private MessageDispatcher $dispatcher;
    private string $channelPrefix;

    /**
     * @param string $basepath  The base URL for the Messenger endpoint,
     *                          e.g. "https://example.com/messenger/qfq"
     * @param string $channelPrefix  Channel prefix, defaults to 'chat'
     */
    public function __construct(string $basepath, string $channelPrefix = CHAT_NCHAN_CHANNEL_PREFIX) {
        $this->channelPrefix = $channelPrefix;
        $this->dispatcher = new MessageDispatcher();
        $this->dispatcher->addPublisher(new HttpPublisher($basepath));
    }

    /**
     * Build the channel name from xId and cIdTopic.
     *
     * @param int $xId  Record ID
     * @param int $cIdTopic  Chat topic ID
     * @return string  Channel name, e.g. "chat-42-1"
     */
    public function buildChannel(int $xId, int $cIdTopic): string {
        return sprintf('%s-%d-%d', $this->channelPrefix, $xId, $cIdTopic);
    }

    /**
     * Publish a "new message" notification.
     *
     * Called after a chat message is saved to notify other clients.
     *
     * @param int $xId  Record ID
     * @param int $cIdTopic  Chat topic ID
     * @param int $cId  Message ID
     * @param bool $chatRoom  Whether this is a chat room message (vs thread)
     * @return array  Array of MessagePublisherError objects (empty on success)
     */
    public function publishNewMessage(int $xId, int $cIdTopic, int $cId, bool $chatRoom): array {
        return $this->dispatcher->publishMessage(
            [$this->buildChannel($xId, $cIdTopic)],
            CHAT_NCHAN_MESSAGE_PING,
            ['cId' => $cId, 'chatRoom' => $chatRoom, 'action' => 'new-message']
        );
    }

    /**
     * Publish a "toolbar update" notification.
     *
     * Called after a tag or done status changes to notify other clients
     * to refresh the toolbar.
     *
     * @param int $xId  Record ID
     * @param int $cIdTopic  Chat topic ID
     * @param int $cId  Message ID
     * @param bool $chatRoom  Whether this is a chat room message (vs thread)
     * @return array  Array of MessagePublisherError objects (empty on success)
     */
    public function publishToolbarUpdate(int $xId, int $cIdTopic, int $cId, bool $chatRoom): array {
        return $this->dispatcher->publishMessage(
            [$this->buildChannel($xId, $cIdTopic)],
            CHAT_NCHAN_MESSAGE_TOOLBAR_PING,
            ['cId' => $cId, 'chatRoom' => $chatRoom, 'action' => 'toolbar-update']
        );
    }
}
