<?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\Extension;
use Builder\Core\Foundation\Resources\Resource;
use Illuminate\Database\Eloquent\Model;

final class BaseResource 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;
    }
}

final class ConcreteExtension extends Extension
{
    /** @return class-string<resource> */
    public static function getExtends(): string
    {
        return BaseResource::class;
    }
}

final class FullExtension extends Extension
{
    /** @return class-string<resource> */
    public static function getExtends(): string
    {
        return BaseResource::class;
    }

    public function fields(): FieldBuilder
    {
        return FieldBuilder::make()->add(
            Section::make('media')->label('Media')->fields([
                Field::make('featured_image_id'),
            ]),
        );
    }

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

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

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

it('getExtends returns the target resource class', function (): void {
    expect(ConcreteExtension::getExtends())->toBe(BaseResource::class);
});

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

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

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

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

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

it('full extension returns eagerLoad', function (): void {
    expect((new FullExtension)->eagerLoad())->toBe(['featuredImage']);
});

it('full extension returns rules', function (): void {
    expect((new FullExtension)->rules('update'))->toHaveKey('featured_image_id');
});

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