<?php

declare(strict_types=1);

use Builder\Core\Foundation\Definition\Field;
use Builder\Core\Foundation\Definition\FieldBuilder;
use Builder\Core\Foundation\Definition\Hook;
use Builder\Core\Foundation\Definition\Section;
use Builder\Core\Foundation\Resources\Resource;
use Illuminate\Database\Eloquent\Model;

// Concrete test resource
final class ConcreteResource extends Resource
{
    public static function getSlug(): string
    {
        return 'items';
    }

    public static function getLabel(): string
    {
        return 'Items';
    }

    /** @return class-string<Model> */
    public static function getModel(): string
    {
        return Model::class;
    }
}

final class FullResource extends Resource
{
    public static function getSlug(): string
    {
        return 'pages';
    }

    public static function getLabel(): string
    {
        return 'Pages';
    }

    /** @return class-string<Model> */
    public static function getModel(): string
    {
        return Model::class;
    }

    public function fields(): FieldBuilder
    {
        return FieldBuilder::make()->add(
            Section::make('content')->label('Content')->fields([
                Field::make('title'),
            ]),
        );
    }

    /** @return list<string> */
    public function eagerLoad(): array
    {
        return ['media'];
    }

    /** @return array<string, mixed> */
    public function rules(string $action): array
    {
        return ['title' => 'required'];
    }

    /** @return list<Hook> */
    public function hooks(): array
    {
        return [Hook::on('saving', function (mixed $model, array $data): void {})];
    }
}

it('getSlug returns the slug', function (): void {
    expect(ConcreteResource::getSlug())->toBe('items');
});

it('getLabel returns the label', function (): void {
    expect(ConcreteResource::getLabel())->toBe('Items');
});

it('getModel returns the model class', function (): void {
    expect(ConcreteResource::getModel())->toBe(Model::class);
});

it('fields defaults to empty FieldBuilder', function (): void {
    expect((new ConcreteResource)->fields()->toSections())->toBe([]);
});

it('eagerLoad defaults to empty array', function (): void {
    expect((new ConcreteResource)->eagerLoad())->toBe([]);
});

it('rules defaults to empty array', function (): void {
    expect((new ConcreteResource)->rules('create'))->toBe([]);
});

it('hooks defaults to empty array', function (): void {
    expect((new ConcreteResource)->hooks())->toBe([]);
});

it('full resource fields builder contains a section with a field', function (): void {
    $builder = (new FullResource)->fields();
    expect($builder->toSections())->toHaveCount(1)
        ->and($builder->toFields())->toHaveCount(1);
});

it('full resource returns eagerLoad', function (): void {
    expect((new FullResource)->eagerLoad())->toBe(['media']);
});

it('full resource returns rules', function (): void {
    expect((new FullResource)->rules('create'))->toBe(['title' => 'required']);
});

it('full resource returns hooks', function (): void {
    expect((new FullResource)->hooks())->toHaveCount(1);
});
