<?php

/**
 * 文件功能：通用大卡片通知广播事件
 *
 * 可向指定用户（私有频道）或房间所有人（Presence 频道）推送全屏大卡片通知。
 * 前端通过 window.chatBanner.show(options) 渲染，支持完全自定义。
 *
 * 使用示例（后端）：
 *
 *   // 推给单个用户
 *   broadcast(new BannerNotification(
 *       target: 'user',
 *       targetId: 'lkddi',
 *       options: [
 *           'icon'      => '💚📩',
 *           'title'     => '好友申请',
 *           'name'      => 'lkddi1',
 *           'body'      => '将你加为好友了！',
 *           'gradient'  => ['#1e3a5f', '#1d4ed8', '#0891b2'],
 *           'autoClose' => 0,
 *           'buttons'   => [
 *               ['label' => '➕ 回加好友', 'color' => '#10b981', 'action' => 'add_friend', 'actionData' => 'lkddi1'],
 *               ['label' => '稍后再说',    'color' => 'rgba(255,255,255,0.15)', 'action' => 'close'],
 *           ],
 *       ]
 *   ));
 *
 *   // 推给整个房间
 *   broadcast(new BannerNotification(target: 'room', targetId: 1, options: [...] ));
 *
 * @author   ChatRoom Laravel
 *
 * @version  1.0.0
 */

namespace App\Events;

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

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

    /**
     * 构造通用大卡片通知事件。
     *
     * @param  string  $target  推送目标类型：'user'（私有频道）| 'room'（房间全员）
     * @param  string|int  $targetId  目标 ID：用户名（user）或 房间 ID（room）
     * @param  array<string, mixed>  $options  前端 chatBanner.show() 选项（详见文件顶部注释）
     */
    public function __construct(
        public readonly string $target,
        public readonly string|int $targetId,
        public readonly array $options = [],
    ) {}

    /**
     * 根据 $target 决定广播到私有频道还是 Presence 频道。
     */
    public function broadcastOn(): Channel
    {
        return match ($this->target) {
            'user' => new PrivateChannel('user.'.$this->targetId),
            'room' => new PresenceChannel('room.'.$this->targetId),
            default => new PrivateChannel('user.'.$this->targetId),
        };
    }

    /**
     * 指定广播事件名称，供前端 .listen('.BannerNotification') 匹配。
     */
    public function broadcastAs(): string
    {
        return 'BannerNotification';
    }

    /**
     * 广播负载：传递完整的 options 给前端渲染。
     *
     * @return array<string, mixed>
     */
    public function broadcastWith(): array
    {
        return [
            'target' => $this->target,
            'target_id' => $this->targetId,
            'options' => $this->options,
        ];
    }
}
