<?php

use App\Models\Branch;
use App\Models\Member;
use App\Models\MemberNote;
use App\Models\User;

test('data_clerk can add a note to a member', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $clerk = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);

    $response = $this->actingAs($clerk)->postJson("/api/v1/members/{$member->id}/notes", [
        'body' => 'Called to follow up on visit.',
    ]);

    $response->assertCreated()->assertJsonPath('data.body', 'Called to follow up on visit.');
});

test('viewer cannot add a note', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $viewer = User::factory()->branchViewer()->create(['branch_id' => $branch->id]);

    $this->actingAs($viewer)->postJson("/api/v1/members/{$member->id}/notes", [
        'body' => 'Should not be allowed.',
    ])->assertStatus(403);
});

test('viewer can read non-private notes', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $viewer = User::factory()->branchViewer()->create(['branch_id' => $branch->id]);
    MemberNote::factory()->create(['member_id' => $member->id, 'is_private' => false]);

    $response = $this->actingAs($viewer)->getJson("/api/v1/members/{$member->id}/notes");

    $response->assertOk();
    expect($response->json('data'))->toHaveCount(1);
});

test('a private note is hidden from other users but visible to its author and super_admin', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $author = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $otherClerk = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $superAdmin = User::factory()->superAdmin()->create();
    MemberNote::factory()->create(['member_id' => $member->id, 'user_id' => $author->id, 'is_private' => true]);

    $asOther = $this->actingAs($otherClerk)->getJson("/api/v1/members/{$member->id}/notes");
    expect($asOther->json('data'))->toHaveCount(0);

    $asAuthor = $this->actingAs($author)->getJson("/api/v1/members/{$member->id}/notes");
    expect($asAuthor->json('data'))->toHaveCount(1);

    $asSuperAdmin = $this->actingAs($superAdmin)->getJson("/api/v1/members/{$member->id}/notes");
    expect($asSuperAdmin->json('data'))->toHaveCount(1);
});

test('an author can delete their own note', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $author = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $note = MemberNote::factory()->create(['member_id' => $member->id, 'user_id' => $author->id]);

    $this->actingAs($author)->deleteJson("/api/v1/member-notes/{$note->id}")->assertStatus(204);
});

test('a different data_clerk cannot delete someone else\'s note', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $author = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $otherClerk = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $note = MemberNote::factory()->create(['member_id' => $member->id, 'user_id' => $author->id]);

    $this->actingAs($otherClerk)->deleteJson("/api/v1/member-notes/{$note->id}")->assertStatus(403);
});

test('branch_admin can delete another user\'s note (moderation)', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);
    $author = User::factory()->dataClerk()->create(['branch_id' => $branch->id]);
    $admin = User::factory()->branchAdmin()->create(['branch_id' => $branch->id]);
    $note = MemberNote::factory()->create(['member_id' => $member->id, 'user_id' => $author->id]);

    $this->actingAs($admin)->deleteJson("/api/v1/member-notes/{$note->id}")->assertStatus(204);
});

test('a user from another branch gets 404 deleting a note', function () {
    $branchA = Branch::factory()->create();
    $branchB = Branch::factory()->create();
    $memberA = Member::factory()->create(['branch_id' => $branchA->id]);
    $note = MemberNote::factory()->create(['member_id' => $memberA->id]);
    $clerkB = User::factory()->dataClerk()->create(['branch_id' => $branchB->id]);

    $this->actingAs($clerkB)->deleteJson("/api/v1/member-notes/{$note->id}")->assertStatus(404);
});

test('unauthenticated request to add a note is rejected', function () {
    $branch = Branch::factory()->create();
    $member = Member::factory()->create(['branch_id' => $branch->id]);

    $this->postJson("/api/v1/members/{$member->id}/notes", ['body' => 'x'])->assertStatus(401);
});
