<?php

/**
 * 文件功能：开发日志发布广播事件
 * 当管理员发布新的开发日志并勾选"通知大厅"时触发
 * 广播至 Room ID=1（星光大厅）的 presence 频道
 * 前端监听此事件并在聊天消息区显示系统通知（含可点击的查看详情链接）
 *
 * @author   ChatRoom Laravel
 *
 * @version  1.0.0
 */

namespace App\Events;

use App\Models\DevChangelog;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

/**
 * 开发日志发布广播事件
 * 负责把更新日志的安全展示字段广播给大厅聊天室。
 */
class ChangelogPublished implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * 构造函数：传入触发通知的日志对象
     *
     * @param  DevChangelog  $changelog  刚发布的开发日志
     */
    public function __construct(
        public readonly DevChangelog $changelog,
    ) {}

    /**
     * 广播频道：仅向 Room 1（星光大厅）的 presence 频道广播
     * 复用现有聊天室频道机制，无需额外配置
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            // 固定广播至 Room ID = 1 的大厅频道
            new PresenceChannel('room.1'),
        ];
    }

    /**
     * 广播事件名称（前端 .listen('ChangelogPublished', ...) 监听此名称）
     */
    public function broadcastAs(): string
    {
        return 'ChangelogPublished';
    }

    /**
     * 广播携带的数据（前端可直接访问）
     *
     * @return array<string, mixed>
     */
    public function broadcastWith(): array
    {
        return [
            'version' => $this->changelog->version,
            'title' => $this->changelog->title,
            'type' => $this->changelog->type,
            'type_label' => $this->changelog->type_label,
            // 同步提供已转义字段，便于前端在 innerHTML 场景下直接复用安全文本。
            'safe_version' => e((string) $this->changelog->version),
            'safe_title' => e((string) $this->changelog->title),
            'safe_type_label' => e((string) $this->changelog->type_label),
            // 前端点击后跳转的目标 URL，自动锚定至对应版本
            'url' => $this->buildDetailUrl(),
        ];
    }

    /**
     * 生成广播使用的更新日志详情地址，并编码版本锚点避免 href 注入。
     */
    private function buildDetailUrl(): string
    {
        return route('changelog.index').'#v'.rawurlencode((string) $this->changelog->version);
    }
}
