<?php

declare(strict_types=1);

use App\Filament\Resources\TenantResource\Pages\ViewTenant;
use App\Filament\Resources\TenantResource\RelationManagers\TenantMembershipsRelationManager;
use App\Models\TenantMembership;
use App\Models\User;
use Livewire\Livewire;

it('allows an owner to add, change role, and remove members', function (): void {
    [$owner, $tenant] = createUserWithTenant(role: 'owner');

    $tenant->makeCurrent();

    $member = User::factory()->create(['name' => 'Member User']);

    Livewire::actingAs($owner)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->callTableAction('add_member', null, [
            'user_id' => $member->getKey(),
            'role' => 'readonly',
        ]);

    $membership = TenantMembership::query()
        ->where('tenant_id', $tenant->getKey())
        ->where('user_id', $member->getKey())
        ->first();

    expect($membership)->not->toBeNull();
    expect($membership?->role)->toBe('readonly');

    Livewire::actingAs($owner)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->callTableAction('change_role', $membership, [
            'role' => 'manager',
        ]);

    expect($membership?->refresh()->role)->toBe('manager');

    Livewire::actingAs($owner)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->callTableAction('remove', $membership);

    expect(TenantMembership::query()->whereKey($membership?->getKey())->exists())->toBeFalse();
});

it('hides membership management actions from non-owners', function (): void {
    [$manager, $tenant] = createUserWithTenant(role: 'manager');

    $tenant->makeCurrent();

    $member = User::factory()->create();
    $member->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'readonly'],
    ]);

    $membership = TenantMembership::query()
        ->where('tenant_id', $tenant->getKey())
        ->where('user_id', $member->getKey())
        ->firstOrFail();

    Livewire::actingAs($manager)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->assertTableActionVisible('add_member')
        ->assertTableActionDisabled('add_member')
        ->assertTableActionVisible('change_role', $membership)
        ->assertTableActionDisabled('change_role', $membership)
        ->assertTableActionVisible('remove', $membership)
        ->assertTableActionDisabled('remove', $membership);
});

it('prevents removing or demoting the last owner', function (): void {
    [$owner, $tenant] = createUserWithTenant(role: 'owner');

    $tenant->makeCurrent();

    $ownerMembership = TenantMembership::query()
        ->where('tenant_id', $tenant->getKey())
        ->where('user_id', $owner->getKey())
        ->firstOrFail();

    Livewire::actingAs($owner)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->callTableAction('change_role', $ownerMembership, [
            'role' => 'manager',
        ]);

    expect($ownerMembership->refresh()->role)->toBe('owner');

    Livewire::actingAs($owner)
        ->test(TenantMembershipsRelationManager::class, [
            'ownerRecord' => $tenant,
            'pageClass' => ViewTenant::class,
        ])
        ->callTableAction('remove', $ownerMembership);

    expect(TenantMembership::query()->whereKey($ownerMembership->getKey())->exists())->toBeTrue();
});
