<?php

declare(strict_types=1);

use Builder\Core\Foundation\Concerns\HasBuilderAccess;
use Illuminate\Database\Eloquent\Collection;

it('returns true when getAllPermissions is not available (no Spatie)', function (): void {
    $user = new class
    {
        use HasBuilderAccess;
    };

    expect($user->canAccessBuilder())->toBeTrue();
});

it('returns wildcard permissions when getAllPermissions is not available (no Spatie)', function (): void {
    $user = new class
    {
        use HasBuilderAccess;
    };

    expect($user->builderPermissions())->toBe(['*']);
});

it('returns true when getAllPermissions contains read:admin', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public function getAllPermissions(): Collection
        {
            return new Collection([(object) ['name' => 'read:admin']]);
        }
    };

    expect($user->canAccessBuilder())->toBeTrue();
});

it('returns false when getAllPermissions does not contain read:admin', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public function getAllPermissions(): Collection
        {
            return new Collection([(object) ['name' => 'read:posts']]);
        }
    };

    expect($user->canAccessBuilder())->toBeFalse();
});

it('returns false when getAllPermissions is empty', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public function getAllPermissions(): Collection
        {
            return new Collection;
        }
    };

    expect($user->canAccessBuilder())->toBeFalse();
});

it('returns permissions from getAllPermissions', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public function getAllPermissions(): Collection
        {
            return new Collection([
                (object) ['name' => 'read:admin'],
                (object) ['name' => 'read:users'],
            ]);
        }
    };

    expect($user->builderPermissions())->toBe(['read:admin', 'read:users']);
});

// ── Widget preferences ────────────────────────────────────────────────────────

it('hiddenWidgets returns empty array when no preferences set', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public ?array $widget_preferences = null;
    };

    expect($user->hiddenWidgets())->toBe([]);
});

it('hiddenWidgets returns hidden_widgets from preferences array', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public array $widget_preferences = ['hidden_widgets' => ['system-info', 'stats']];
    };

    expect($user->hiddenWidgets())->toBe(['system-info', 'stats']);
});

it('hiddenWidgets handles JSON string preferences', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public string $widget_preferences = '{"hidden_widgets":["system-info"]}';
    };

    expect($user->hiddenWidgets())->toBe(['system-info']);
});

it('toggleWidget adds key to hidden_widgets when not present', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public array $widget_preferences = [];

        public function update(array $data): bool
        {
            $this->widget_preferences = $data['widget_preferences'];

            return true;
        }
    };

    $user->toggleWidget('system-info');

    expect($user->hiddenWidgets())->toContain('system-info');
});

it('toggleWidget removes key from hidden_widgets when already hidden', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public array $widget_preferences = ['hidden_widgets' => ['system-info']];

        public function update(array $data): bool
        {
            $this->widget_preferences = $data['widget_preferences'];

            return true;
        }
    };

    $user->toggleWidget('system-info');

    expect($user->hiddenWidgets())->not->toContain('system-info');
});

it('toggleWidget falls back to direct assignment when update() is unavailable', function (): void {
    $user = new class
    {
        use HasBuilderAccess;

        public ?array $widget_preferences = null;
    };

    $user->toggleWidget('system-info');

    expect($user->hiddenWidgets())->toBe(['system-info']);
});
