<?php

declare(strict_types=1);

use Builder\Core\Foundation\Resources\RecordAction;
use Illuminate\Http\Request;

it('make creates a RecordAction with key as default label', function (): void {
    $action = RecordAction::make('publish');

    expect($action->key)->toBe('publish')
        ->and($action->getLabel())->toBe('publish');
});

it('label sets a string label', function (): void {
    $action = RecordAction::make('publish')->label('Publish Post');

    expect($action->getLabel())->toBe('Publish Post');
});

it('label accepts a closure and resolves it lazily', function (): void {
    $action = RecordAction::make('publish')->label(fn (): string => 'Dynamic Label');

    expect($action->getLabel())->toBe('Dynamic Label');
});

it('permission() sets the permission and getPermission() returns it', function (): void {
    $action = RecordAction::make('publish')->permission('publish-posts');

    expect($action->getPermission())->toBe('publish-posts');
});

it('permission() with null sets no permission requirement', function (): void {
    $action = RecordAction::make('publish')->permission(null);

    expect($action->getPermission())->toBeNull();
});

it('getPermission() defaults to null', function (): void {
    $action = RecordAction::make('view');

    expect($action->getPermission())->toBeNull();
});

it('confirm() sets confirm to true and isConfirm() returns true', function (): void {
    $action = RecordAction::make('delete')->confirm();

    expect($action->isConfirm())->toBeTrue();
});

it('confirm(false) sets confirm to false', function (): void {
    $action = RecordAction::make('delete')->confirm(false);

    expect($action->isConfirm())->toBeFalse();
});

it('isConfirm() defaults to false', function (): void {
    $action = RecordAction::make('view');

    expect($action->isConfirm())->toBeFalse();
});

it('visibleFor controls isVisibleFor result', function (): void {
    $action = RecordAction::make('archive')->visibleFor(fn (mixed $record): bool => (bool) $record['active']);

    expect($action->isVisibleFor(['active' => true]))->toBeTrue()
        ->and($action->isVisibleFor(['active' => false]))->toBeFalse();
});

it('isVisibleFor returns true when no condition is set', function (): void {
    $action = RecordAction::make('view');

    expect($action->isVisibleFor(['anything' => 'here']))->toBeTrue();
});

it('execute calls the handler with record and request', function (): void {
    $called = false;
    $action = RecordAction::make('publish')->handler(function (mixed $record, Request $request) use (&$called): void {
        $called = true;
    });

    $action->execute(['id' => 1], new Request);

    expect($called)->toBeTrue();
});

it('toArray includes key, label, and confirm', function (): void {
    $action = RecordAction::make('approve')
        ->label('Approve')
        ->permission('approve-items')
        ->confirm();

    $array = $action->toArray();

    expect($array)->toMatchArray([
        'key' => 'approve',
        'label' => 'Approve',
        'confirm' => true,
    ]);
});
