<?php

namespace App\Events;

use App\Models\ChatMessage;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

/**
 * Broadcast a new chat message to all participants in the room.
 *
 * This event is fired by ChatController::sendMessage() after the message
 * is persisted. It is broadcast on the private channel `chat.{chatId}`,
 * which is authorised in channels.php — only non-blocked participants
 * can subscribe, so they are the only ones who receive the event.
 *
 * Client-side (Echo) usage:
 *
 *   Echo.private(`chat.${chatId}`)
 *       .listen('MessageSent', (e) => {
 *           console.log(e.message); // ChatMessage payload
 *       });
 */
class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public ChatMessage $message;

    public function __construct(ChatMessage $message)
    {
        $this->message = $message;
    }

    /**
     * Broadcast on the private channel for this chat room.
     * The channel auth is handled in channels.php.
     */
    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('chat.' . $this->message->chat_id),
        ];
    }

    /**
     * Explicit event name so the JS client can listen with
     * .listen('MessageSent', ...) regardless of PHP namespace.
     */
    public function broadcastAs(): string
    {
        return 'MessageSent';
    }

    /**
     * Only broadcast the fields the client actually needs.
     * Avoids leaking internal DB fields over the wire.
     */
    public function broadcastWith(): array
    {
        return [
            'message' => [
                'message_id'   => $this->message->message_id,
                'chat_id'      => $this->message->chat_id,
                'sender_id'    => $this->message->sender_id,
                'sender_name'  => $this->message->senderUser?->name,
                'message_type' => $this->message->message_type,
                'message'      => $this->message->message,
                'file_id'      => $this->message->file_id,
                'is_read'      => $this->message->is_read,
                'sent_at'      => $this->message->sent_at?->toISOString(),
            ],
        ];
    }
}