<?php

/**
 * 文件功能：聊天室全屏特效广播事件
 *
 * 管理员或用户购买单次卡后触发，通过 WebSocket 广播给房间内用户播放 Canvas 动画。
 * 支持指定接收者；当存在 target_username 时，触发者本人和指定接收者都应可见。
 *
 * @author   ChatRoom Laravel
 *
 * @version  2.0.0
 */

namespace App\Events;

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

class EffectBroadcast implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * 支持的特效类型列表（用于校验）
     */
    public const TYPES = ['fireworks', 'rain', 'lightning', 'snow', 'sakura', 'meteors', 'gold-rain', 'hearts', 'confetti', 'fireflies'];

    /**
     * 构造函数
     *
     * @param  int  $roomId  房间 ID
     * @param  string  $type  特效类型：fireworks / rain / lightning / snow / sakura / meteors / gold-rain / hearts / confetti / fireflies
     * @param  string  $operator  触发特效的用户名（购买者）
     * @param  string|null  $targetUsername  接收者用户名（null = 全员）
     * @param  string|null  $giftMessage  附带赠言
     */
    public function __construct(
        public readonly int $roomId,
        public readonly string $type,
        public readonly string $operator,
        public readonly ?string $targetUsername = null,
        public readonly ?string $giftMessage = null,
    ) {}

    /**
     * 广播频道：向房间内所有在线用户推送
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new PresenceChannel('room.'.$this->roomId),
        ];
    }

    /**
     * 广播数据：特效类型、操作者、目标用户、赠言
     * 前端据此判断“全员可见”或“仅操作者 + 指定接收者可见”。
     *
     * @return array<string, mixed>
     */
    public function broadcastWith(): array
    {
        return [
            'type' => $this->type,
            'operator' => $this->operator,
            'target_username' => $this->targetUsername,   // null = 全员
            'gift_message' => $this->giftMessage,
        ];
    }
}
