<?php

use App\Models\Declaration;
use App\Models\User;
use App\Models\Workspace;
use App\Notifications\DocumentUploadedNotification;
use App\Notifications\NudgeNotification;
use Illuminate\Support\Facades\Mail;
use Inertia\Testing\AssertableInertia;

function setupNotificationCenterTest(): array
{
    Mail::fake();

    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();
    $workspace->users()->attach($user->id, ['role' => 'owner', 'permissions' => []]);

    session(['current_workspace_id' => $workspace->id]);

    $declaration = Declaration::factory()->forWorkspace($workspace)->create();

    return [$user, $workspace, $declaration];
}

// ── AC #1: Dropdown rendering ────────────────────────────

test('notification dropdown renders with unread count badge via shared props', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();
    $sender = User::factory()->create();

    $user->notify(new NudgeNotification($declaration, $sender));
    $user->notify(new NudgeNotification($declaration, $sender));

    $response = $this->actingAs($user)->get(route('dashboard'));

    $response->assertOk();
    $response->assertInertia(fn (AssertableInertia $page) => $page
        ->has('userNotifications')
        ->where('userNotifications.unread_count', 2)
        ->has('userNotifications.readUrl')
        ->has('userNotifications.readAllUrl')
        ->has('userNotifications.notificationsUrl')
    );
});

// ── AC #1: Clicking notification marks as read ───────────

test('clicking notification marks it as read via POST to notifications.read', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();
    $sender = User::factory()->create();

    $user->notify(new NudgeNotification($declaration, $sender));
    $notification = $user->notifications()->first();
    expect($notification->read_at)->toBeNull();

    $response = $this->actingAs($user)->post(route('notifications.read', $notification->id));

    $response->assertRedirect();
    $notification->refresh();
    expect($notification->read_at)->not->toBeNull();
});

// ── AC #1: Mark all as read ──────────────────────────────

test('mark all as read clears unread count for current workspace', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();
    $sender = User::factory()->create();

    $user->notify(new NudgeNotification($declaration, $sender));
    $user->notify(new DocumentUploadedNotification($declaration, 1));

    expect($user->unreadNotifications()->count())->toBe(2);

    $response = $this->actingAs($user)->post(route('notifications.readAll'));

    $response->assertRedirect();
    $user->refresh();
    expect($user->unreadNotifications()->count())->toBe(0);
});

// ── AC #2: Full page renders with workspace-scoped notifications ──

test('notifications page renders with workspace-scoped notifications', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();
    $sender = User::factory()->create();

    $user->notify(new NudgeNotification($declaration, $sender));

    $response = $this->actingAs($user)->get(route('notifications.index'));

    $response->assertOk();
    $response->assertInertia(fn (AssertableInertia $page) => $page
        ->component('notifications/Index')
        ->has('notifications.data', 1)
        ->has('markAllReadUrl')
        ->has('readUrl')
    );
});

// ── AC #2: Pagination at 25 per page ─────────────────────

test('notifications page pagination works at 25 per page', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();

    for ($i = 0; $i < 30; $i++) {
        $user->notify(new DocumentUploadedNotification($declaration, 1));
    }

    $response = $this->actingAs($user)->get(route('notifications.index'));

    $response->assertOk();
    $response->assertInertia(fn (AssertableInertia $page) => $page
        ->component('notifications/Index')
        ->has('notifications.data', 25)
        ->where('notifications.last_page', 2)
    );
});

// ── AC #3: Empty state renders when no notifications ─────

test('empty state renders when no notifications exist', function () {
    [$user, $workspace, $declaration] = setupNotificationCenterTest();

    $response = $this->actingAs($user)->get(route('notifications.index'));

    $response->assertOk();
    $response->assertInertia(fn (AssertableInertia $page) => $page
        ->component('notifications/Index')
        ->has('notifications.data', 0)
    );
});

// ── AC #2: Cross-workspace isolation ─────────────────────

test('notifications are scoped to current workspace and do not leak across workspaces', function () {
    [$user, $workspace1, $declaration1] = setupNotificationCenterTest();

    $workspace2 = Workspace::factory()->create();
    $workspace2->users()->attach($user->id, ['role' => 'owner', 'permissions' => []]);
    $declaration2 = Declaration::factory()->forWorkspace($workspace2)->create();

    // Notify for both workspaces
    $user->notify(new DocumentUploadedNotification($declaration1, 1));
    $user->notify(new DocumentUploadedNotification($declaration2, 1));

    // Session is set to workspace1
    $response = $this->actingAs($user)->get(route('notifications.index'));

    $response->assertOk();
    $response->assertInertia(fn (AssertableInertia $page) => $page
        ->component('notifications/Index')
        ->has('notifications.data', 1)
        ->where('notifications.data.0.data.workspace_id', $workspace1->id)
    );
});
