<?php

declare(strict_types=1);

use Builder\Core\Foundation\Definition\MenuItem;

it('make creates a MenuItem instance', function (): void {
    expect(MenuItem::make('pages'))->toBeInstanceOf(MenuItem::class);
});

it('key defaults as label', function (): void {
    expect(MenuItem::make('pages')->getLabel())->toBe('pages');
});

it('label sets and returns self', function (): void {
    $item = MenuItem::make('pages');
    $result = $item->label('Pagina\'s');

    expect($result)->toBe($item)
        ->and($item->getLabel())->toBe("Pagina's");
});

it('icon defaults to null', function (): void {
    expect(MenuItem::make('pages')->getIcon())->toBeNull();
});

it('icon sets and returns self', function (): void {
    $item = MenuItem::make('pages');
    $result = $item->icon('document');

    expect($result)->toBe($item)
        ->and($item->getIcon())->toBe('document');
});

it('route defaults to null', function (): void {
    expect(MenuItem::make('pages')->getRoute())->toBeNull();
});

it('route sets and returns self', function (): void {
    $item = MenuItem::make('pages');
    $result = $item->route('builder.resource.index');

    expect($result)->toBe($item)
        ->and($item->getRoute())->toBe('builder.resource.index');
});

it('priority defaults to 0', function (): void {
    expect(MenuItem::make('pages')->getPriority())->toBe(0);
});

it('priority sets and returns self', function (): void {
    $item = MenuItem::make('pages');
    $result = $item->priority(10);

    expect($result)->toBe($item)
        ->and($item->getPriority())->toBe(10);
});

it('getKey returns key', function (): void {
    expect(MenuItem::make('media')->getKey())->toBe('media');
});

it('getBadgeValue returns null when no badge', function (): void {
    expect(MenuItem::make('pages')->getBadgeValue())->toBeNull();
});

it('badge sets closure and getBadgeValue calls it', function (): void {
    $item = MenuItem::make('pages')->badge(fn (): int => 5);

    expect($item->getBadgeValue())->toBe(5);
});

it('children defaults to empty array', function (): void {
    expect(MenuItem::make('pages')->getChildren())->toBe([]);
});

it('children sets and returns self', function (): void {
    $child = MenuItem::make('sub');
    $item = MenuItem::make('pages');
    $result = $item->children([$child]);

    expect($result)->toBe($item)
        ->and($item->getChildren())->toBe([$child]);
});

it('toArray returns correct structure', function (): void {
    $item = MenuItem::make('pages')
        ->label("Pagina's")
        ->icon('document')
        ->route('builder.resource.index')
        ->priority(5);

    $array = $item->toArray();

    expect($array)->toBe([
        'key' => 'pages',
        'label' => "Pagina's",
        'icon' => 'document',
        'route' => 'builder.resource.index',
        'priority' => 5,
        'badge' => null,
        'permission' => null,
        'children' => [],
    ]);
});

it('filterChildren returns only allowed children', function (): void {
    $open = MenuItem::make('open');
    $restricted = MenuItem::make('restricted')->permission('admin-only');
    $parent = MenuItem::make('parent')->children([$open, $restricted]);

    expect($parent->filterChildren([]))->toHaveCount(1)
        ->and($parent->filterChildren([])[0]->getKey())->toBe('open');
});

it('filterChildren returns all children when user has wildcard permission', function (): void {
    $open = MenuItem::make('open');
    $restricted = MenuItem::make('restricted')->permission('admin-only');
    $parent = MenuItem::make('parent')->children([$open, $restricted]);

    expect($parent->filterChildren(['*']))->toHaveCount(2);
});

it('toArray includes serialized children', function (): void {
    $child = MenuItem::make('sub')->label('Sub');
    $parent = MenuItem::make('parent')->children([$child]);

    $array = $parent->toArray();

    expect($array['children'])->toHaveCount(1)
        ->and($array['children'][0]['key'])->toBe('sub');
});
