<?php

declare(strict_types=1);

use Builder\Core\Foundation\Tables\Filter;

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

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

it('label() sets label', function (): void {
    expect(Filter::make('status')->label('Status')->getLabel())->toBe('Status');
});

it('type defaults to text', function (): void {
    expect(Filter::make('status')->getType())->toBe('text');
});

it('type() sets type', function (): void {
    expect(Filter::make('status')->type('select')->getType())->toBe('select');
});

it('options() sets array options', function (): void {
    $filter = Filter::make('status')->options(['active' => 'Active', 'inactive' => 'Inactive']);

    expect($filter->getOptions())->toBe(['active' => 'Active', 'inactive' => 'Inactive']);
});

it('options() accepts Closure and resolves lazily', function (): void {
    $filter = Filter::make('status')->options(fn () => ['a' => 'A']);

    expect($filter->getOptions())->toBe(['a' => 'A']);
});

it('options is null by default', function (): void {
    expect(Filter::make('status')->getOptions())->toBeNull();
});

it('apply() sets apply closure', function (): void {
    $fn = fn ($q, $v): mixed => $q;
    $filter = Filter::make('status')->apply($fn);

    expect($filter->getApply())->toBe($fn);
});

it('apply is null by default', function (): void {
    expect(Filter::make('status')->getApply())->toBeNull();
});

it('getKey() returns the key', function (): void {
    expect(Filter::make('status')->getKey())->toBe('status');
});

it('toArray() excludes apply closure', function (): void {
    $filter = Filter::make('status')
        ->label('Status')
        ->type('select')
        ->options(['a' => 'A'])
        ->apply(fn ($q, $v): mixed => $q);

    $array = $filter->toArray();

    expect($array)->toBe([
        'key' => 'status',
        'label' => 'Status',
        'type' => 'select',
        'options' => ['a' => 'A'],
    ])->and($array)->not->toHaveKey('apply');
});

it('toArray() resolves options Closure', function (): void {
    $filter = Filter::make('status')->options(fn () => ['x' => 'X']);

    expect($filter->toArray()['options'])->toBe(['x' => 'X']);
});
