<?php

declare(strict_types=1);

use App\Support\Livewire\TrustedState\TrustedStateClass;
use App\Support\Livewire\TrustedState\TrustedStatePolicy;
use App\Support\Livewire\TrustedState\TrustedStateResolver;
use App\Support\Workspaces\WorkspaceContext;

function livewireTrustedStateFirstSliceFixtures(): array
{
    return [
        TrustedStatePolicy::MANAGED_ENVIRONMENT_ONBOARDING_WIZARD => 'app/Filament/Pages/Workspaces/ManagedEnvironmentOnboardingWizard.php',
        TrustedStatePolicy::TENANT_REQUIRED_PERMISSIONS => 'app/Filament/Pages/EnvironmentRequiredPermissions.php',
    ];
}

function livewireTrustedStateFieldGroups(array $componentPolicy): array
{
    return [
        'locked_identity_fields' => $componentPolicy['locked_identity_fields'],
        'mutable_selector_fields' => $componentPolicy['mutable_selector_fields'],
        'server_derived_authority_fields' => $componentPolicy['server_derived_authority_fields'],
    ];
}

it('documents a first-slice trusted-state policy for every guarded surface', function (): void {
    $policy = app(TrustedStatePolicy::class);

    expect($policy->components())
        ->toBe(array_keys(livewireTrustedStateFirstSliceFixtures()));

    foreach (livewireTrustedStateFirstSliceFixtures() as $component => $relativePath) {
        expect(file_exists(base_path($relativePath)))->toBeTrue();
        expect($policy->forComponent($component)['component_name'])->not->toBe('');
    }
});

it('keeps first-slice policies explicit about state lanes and authority sources', function (): void {
    $policy = app(TrustedStatePolicy::class);
    $validClasses = array_map(
        static fn (TrustedStateClass $class): string => $class->value,
        TrustedStateClass::cases(),
    );

    expect($validClasses)->toContain('presentation', 'locked_identity', 'server_derived_authority');

    foreach ($policy->firstSlice() as $componentPolicy) {
        expect($componentPolicy['plane'])->not->toBe('')
            ->and($componentPolicy['authority_sources'])->not->toBeEmpty()
            ->and($componentPolicy['mutable_selectors'])->toBeArray()
            ->and($componentPolicy['locked_identities'])->toBeArray()
            ->and($componentPolicy['locked_identity_fields'])->toBeArray()
            ->and($componentPolicy['mutable_selector_fields'])->toBeArray()
            ->and($componentPolicy['server_derived_authority_fields'])->toBeArray()
            ->and($componentPolicy['forbidden_public_authority_fields'])->toBeArray();
    }
});

it('keeps the first-slice trusted-state inventory implementation-backed', function (): void {
    $policy = app(TrustedStatePolicy::class);

    foreach (livewireTrustedStateFirstSliceFixtures() as $component => $relativePath) {
        $componentPolicy = $policy->forComponent($component);
        $contents = file_get_contents(base_path($relativePath));

        expect($contents)->not->toBeFalse();

        foreach (livewireTrustedStateFieldGroups($componentPolicy) as $groupName => $fields) {
            foreach ($fields as $field) {
                expect($field['notes'])->not->toBe('');
                expect($field['implementation_markers'])->not->toBeEmpty();

                $expectedStateClass = match ($groupName) {
                    'locked_identity_fields' => TrustedStateClass::LockedIdentity->value,
                    'mutable_selector_fields' => TrustedStateClass::Presentation->value,
                    'server_derived_authority_fields' => TrustedStateClass::ServerDerivedAuthority->value,
                    default => throw new InvalidArgumentException('Unknown trusted-state group.'),
                };

                expect($field['state_class'])->toBe($expectedStateClass);

                foreach ($field['implementation_markers'] as $marker) {
                    if (str_contains($marker, PHP_EOL)) {
                        $pattern = '/'.str_replace(
                            ['\\ '.preg_quote(PHP_EOL, '/').'\\ ', '\\ '.preg_quote(PHP_EOL, '/'), preg_quote(PHP_EOL, '/').'\\ '],
                            ['\\s+', '\\s+', '\\s+'],
                            preg_quote($marker, '/')
                        ).'/s';

                        expect(preg_match($pattern, (string) $contents))
                            ->toBe(1, "Missing implementation marker [{$marker}] for {$component}.{$field['name']}");

                        continue;
                    }

                    expect(str_contains((string) $contents, $marker))
                        ->toBeTrue("Missing implementation marker [{$marker}] for {$component}.{$field['name']}");
                }
            }
        }
    }
});

it('documents first-slice trusted-state helper semantics through reusable enum and resolver APIs', function (): void {
    $policy = app(TrustedStatePolicy::class);
    $resolver = app(TrustedStateResolver::class);

    expect(TrustedStateClass::Presentation->allowsClientMutation())->toBeTrue()
        ->and(TrustedStateClass::Presentation->requiresServerRevalidation())->toBeFalse()
        ->and(TrustedStateClass::LockedIdentity->allowsClientMutation())->toBeFalse()
        ->and(TrustedStateClass::LockedIdentity->requiresServerRevalidation())->toBeTrue()
        ->and(TrustedStateClass::ServerDerivedAuthority->allowsClientMutation())->toBeFalse()
        ->and(TrustedStateClass::ServerDerivedAuthority->requiresServerRevalidation())->toBeTrue();

    foreach ($policy->components() as $component) {
        expect($resolver->requiredAuthoritySources($component, $policy))
            ->toBe($policy->forComponent($component)['authority_sources']);
    }
});

it('binds the shared trusted-state resolver through the container', function (): void {
    expect(app(TrustedStateResolver::class))->toBeInstanceOf(TrustedStateResolver::class)
        ->and(app(WorkspaceContext::class))->toBeInstanceOf(WorkspaceContext::class);
});
