<?php

use App\Models\Hunts;
use App\Models\User;
use App\Notifications\HuntParticipantJoinedNotification;
use App\Notifications\VerifyEmailNotification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;

uses(RefreshDatabase::class);

it('notifies the hunt creator when a user joins their hunt', function () {
    Notification::fake();

    $creator = User::factory()->create();
    $participant = User::factory()->create();
    $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([
        'creator_id' => $creator->id,
    ]));

    $response = $this
        ->actingAs($participant, 'sanctum')
        ->postJson("/api/hunts/{$hunt->id}/participate");

    $response
        ->assertOk()
        ->assertJson([
            'message' => 'Successfully joined the hunt',
        ]);

    Notification::assertSentTo(
        $creator,
        HuntParticipantJoinedNotification::class,
        fn (HuntParticipantJoinedNotification $notification): bool => $notification->hunt->is($hunt)
            && $notification->participant->is($participant)
            && $notification instanceof ShouldQueue,
    );
});

it('does not notify the hunt creator when the user already participates', function () {
    Notification::fake();

    $creator = User::factory()->create();
    $participant = User::factory()->create();
    $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([
        'creator_id' => $creator->id,
    ]));

    $hunt->participants()->attach($participant->id, [
        'current_step_number' => 0,
        'status' => 'in_progress',
    ]);

    $response = $this
        ->actingAs($participant, 'sanctum')
        ->postJson("/api/hunts/{$hunt->id}/participate");

    $response->assertConflict();

    Notification::assertNotSentTo($creator, HuntParticipantJoinedNotification::class);
});

it('uses the personalized joined hunt email view', function () {
    $creator = User::factory()->create([
        'username' => 'creator-test',
    ]);
    $participant = User::factory()->create([
        'username' => 'participant-test',
    ]);
    $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([
        'creator_id' => $creator->id,
        'title' => 'La quête des lanternes',
        'city' => 'Lyon',
    ]));

    $hunt->participants()->attach($participant->id, [
        'current_step_number' => 0,
        'status' => 'in_progress',
    ]);

    $notification = new HuntParticipantJoinedNotification($hunt, $participant);
    $mailMessage = $notification->toMail($creator);

    expect($mailMessage->subject)->toBe('Nouveau participant sur La quête des lanternes')
        ->and($mailMessage->view)->toBe('mail.hunts.joined-hunt')
        ->and($mailMessage->viewData)
        ->toMatchArray([
            'notifiable' => $creator,
            'hunt' => $hunt,
            'participant' => $participant,
            'participantsCount' => 1,
        ]);

    $renderedView = view($mailMessage->view, $mailMessage->viewData)->render();

    expect($renderedView)
        ->toContain('Bonjour creator-test')
        ->toContain('participant-test')
        ->toContain('La quête des lanternes')
        ->toContain('Lyon');
});

it('queues email verification notifications', function () {
    expect(new VerifyEmailNotification)->toBeInstanceOf(ShouldQueue::class);
});
