<?php

declare(strict_types=1);

use App\Filament\Resources\BaselineProfileResource\Pages\CreateBaselineProfile;
use App\Filament\Resources\BaselineProfileResource\Pages\EditBaselineProfile;
use App\Models\BaselineProfile;
use Filament\Forms\Components\Select;
use Illuminate\Validation\ValidationException;
use Livewire\Livewire;

it('shows only baseline-supported foundation types in the baseline profile scope picker', function (): void {
    [$user] = createUserWithTenant(role: 'owner');

    Livewire::actingAs($user)
        ->test(CreateBaselineProfile::class)
        ->assertOk()
        ->assertFormFieldExists('scope_jsonb.foundation_types', function (Select $field): bool {
            $options = $field->getOptions();

            return $field->isMultiple()
                && ($options['assignmentFilter'] ?? null) === 'Assignment Filter'
                && ($options['intuneRoleDefinition'] ?? null) === 'Intune RBAC Role Definition'
                && ! array_key_exists('intuneRoleAssignment', $options);
        });
});

it('persists baseline-supported foundation types on baseline profile create', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    Livewire::actingAs($user)
        ->test(CreateBaselineProfile::class)
        ->fillForm([
            'name' => 'RBAC baseline',
            'scope_jsonb.policy_types' => [],
            'scope_jsonb.foundation_types' => ['intuneRoleDefinition'],
        ])
        ->call('create')
        ->assertHasNoFormErrors()
        ->assertNotified();

    $profile = BaselineProfile::query()
        ->where('workspace_id', (int) $tenant->workspace_id)
        ->where('name', 'RBAC baseline')
        ->sole();

    expect(data_get($profile->scope_jsonb, 'foundation_types'))
        ->toBe(['intuneRoleDefinition']);
});

it('rejects unsupported foundation types when baseline profile scope is submitted', function (): void {
    [$user] = createUserWithTenant(role: 'owner');

    Livewire::actingAs($user)
        ->test(CreateBaselineProfile::class)
        ->fillForm([
            'name' => 'Invalid RBAC baseline',
            'scope_jsonb.policy_types' => [],
            'scope_jsonb.foundation_types' => ['intuneRoleAssignment'],
        ])
        ->call('create')
        ->assertHasFormErrors(['scope_jsonb.foundation_types.0' => ['in']]);

    expect(BaselineProfile::query()->where('name', 'Invalid RBAC baseline')->exists())->toBeFalse();
});

it('rejects inactive canonical foundation subject types when editing a baseline profile', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'name' => 'Editable RBAC baseline',
    ]);

    $component = Livewire::actingAs($user)
        ->test(EditBaselineProfile::class, ['record' => $profile->getKey()]);

    $page = $component->instance();
    $method = new \ReflectionMethod($page, 'mutateFormDataBeforeSave');
    $method->setAccessible(true);

    expect(fn () => $method->invoke($page, [
        'scope_jsonb' => [
            'version' => 2,
            'entries' => [
                [
                    'domain_key' => 'platform_foundation',
                    'subject_class' => 'configuration_resource',
                    'subject_type_keys' => ['intuneRoleAssignment'],
                    'filters' => [],
                ],
            ],
        ],
    ]))->toThrow(ValidationException::class, 'Inactive subject type');
});
