<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Support\Facades\Event;

use App\Models\Chat;
use App\Models\User;
use App\Models\Livestream;

use App\Events\WhisperCreated;

class ChatTest extends TestCase
{
    public function test_a_chat_belongs_to_a_user()
    {
        $chat = Chat::factory()->create();
        $this->assertNotNull($chat->user);
        $this->assertInstanceOf(User::class, $chat->user);
    }

    public function test_a_chat_message_has_a_deleted_attribute()
    {
        $chat = Chat::factory()->create();
        $chat->delete();
        $chat->refresh();

        $this->assertNotNull($chat->deleted);
        $this->assertTrue($chat->deleted);
    }

    public function test_a_chat_can_have_many_whispers()
    {
        $user = User::factory()->create();
        $chat = Chat::factory()->create();
        $chat->whispers()->attach($user);

        $this->assertEquals(1, $chat->whispers->count());
        $this->assertTrue($chat->whispers->contains('id', $user->id));
    }

    public function test_an_object_can_be_found_for_a_chat()
    {
        $livestream = Livestream::factory()->create();
        $room = $livestream->chat_room;

        $this->assertEquals($livestream->id, Chat::findObject($room)->id);
        $this->assertEquals(get_class($livestream), get_class(Chat::findObject($room)));
    }

    public function test_a_chat_can_send_a_whisper_to_users()
    {
        $user = User::factory()->create();
        $chat = Chat::factory()->create();

        Event::fake();

        $chat->sendWhisperToUsers($user);

        Event::assertDispatched(function (WhisperCreated $event) use ($chat, $user) {
            return $event->chat->message === $chat->message && $event->user->id === $user->id;
        });
    }

    public function test_a_moderator_has_permission_to_select_a_chat()
    {
        $user = User::factory()->create();
        $livestream = Livestream::factory()->create();
        $chat = Chat::factory()->create([
            'room' => 'livestream.'.$livestream->id,
        ]);

        $this->assertFalse($user->can('select', $chat));

        $livestream->createPermission('moderate', $user);

        $user->refresh();

        $this->assertTrue($user->can('select', $chat));

    }

    public function test_a_chat_has_a_replying_to()
    {
        $livestream = Livestream::factory()->create();

        $chat1 = Chat::factory()->create([
            'room' => 'livestream.'.$livestream->id,
        ]);

        $chat2 = Chat::factory()->create([
            'room' => 'livestream.'.$livestream->id,
            'reply_id' => $chat1->id,
        ]);

        $this->assertNotNull($chat2->reply);
        $this->assertEquals($chat1->message, $chat2->reply->message);
    }

    public function test_livestream_managers_get_whispers()
    {
        $user = User::factory()->create();
        $user->addRole('livestreams-manager');
        $chat = Chat::factory()->create();

        Event::fake();

        $chat->sendMessageToMods(collect());

        Event::assertDispatched(function (WhisperCreated $event) use ($chat, $user) {
            return $event->chat->message === $chat->message && $event->user->id === $user->id;
        });
    }
}
