<?php

declare(strict_types=1);

use Builder\Core\Foundation\Tables\RowAction;

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

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

it('label() sets label', function (): void {
    expect(RowAction::make('edit')->label('Edit Record')->getLabel())->toBe('Edit Record');
});

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

it('icon() sets icon', function (): void {
    expect(RowAction::make('edit')->icon('pencil')->getIcon())->toBe('pencil');
});

it('permission defaults to null', function (): void {
    expect(RowAction::make('edit')->getPermission())->toBeNull();
});

it('permission() sets permission', function (): void {
    expect(RowAction::make('edit')->permission('update:users')->getPermission())->toBe('update:users');
});

it('destructive defaults to false', function (): void {
    expect(RowAction::make('delete')->isDestructive())->toBeFalse();
});

it('destructive() sets destructive flag', function (): void {
    expect(RowAction::make('delete')->destructive()->isDestructive())->toBeTrue();
});

it('destructive(false) unsets flag', function (): void {
    expect(RowAction::make('delete')->destructive(false)->isDestructive())->toBeFalse();
});

it('confirm() sets title and message', function (): void {
    $action = RowAction::make('delete')->confirm('Delete?', 'This cannot be undone.');

    expect($action->getConfirmTitle())->toBe('Delete?')
        ->and($action->getConfirmMessage())->toBe('This cannot be undone.');
});

it('confirm title and message default to null', function (): void {
    $action = RowAction::make('delete');

    expect($action->getConfirmTitle())->toBeNull()
        ->and($action->getConfirmMessage())->toBeNull();
});

it('url() sets static URL', function (): void {
    $action = RowAction::make('edit')->url('/admin/users/1/edit');

    expect($action->resolveUrl([]))->toBe('/admin/users/1/edit');
});

it('urlUsing() sets dynamic URL resolver', function (): void {
    $action = RowAction::make('edit')->urlUsing(fn (array $record): string => "/admin/users/{$record['id']}/edit");

    expect($action->resolveUrl(['id' => 42]))->toBe('/admin/users/42/edit');
});

it('resolveUrl returns null when neither url nor urlUsing is set', function (): void {
    expect(RowAction::make('custom')->resolveUrl([]))->toBeNull();
});

it('urlUsing takes precedence over url when both set', function (): void {
    $action = RowAction::make('edit')
        ->url('/static-url')
        ->urlUsing(fn (array $record): string => "/dynamic/{$record['id']}");

    expect($action->resolveUrl(['id' => 5]))->toBe('/dynamic/5');
});

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

it('toArray() resolves URL and excludes Closure', function (): void {
    $action = RowAction::make('edit')
        ->label('Edit')
        ->icon('pencil')
        ->permission('update:users')
        ->urlUsing(fn (array $record): string => "/admin/users/{$record['id']}/edit");

    $array = $action->toArray(['id' => 7]);

    expect($array)->toBe([
        'key' => 'edit',
        'label' => 'Edit',
        'icon' => 'pencil',
        'url' => '/admin/users/7/edit',
        'method' => 'get',
        'permission' => 'update:users',
        'destructive' => false,
        'confirm' => null,
    ])->and($array)->not->toHaveKey('urlUsing');
});

it('toArray() includes confirm when set', function (): void {
    $action = RowAction::make('delete')
        ->label('Delete')
        ->destructive()
        ->confirm('Delete record?', 'This cannot be undone.');

    $array = $action->toArray(['id' => 3]);

    expect($array['confirm'])->toBe([
        'title' => 'Delete record?',
        'message' => 'This cannot be undone.',
    ])
        ->and($array['destructive'])->toBeTrue();
});

it('method() sets the HTTP method on the action', function (): void {
    $action = RowAction::make('publish')->method('POST');

    expect($action->toArray([])['method'])->toBe('post');
});
