<?php

declare(strict_types=1);

use Builder\Core\Extensions\Account\AccountProfile;
use Builder\Core\Foundation\Account\AccountDefinition;
use Builder\Core\Foundation\Account\AccountExtension;
use Builder\Core\Foundation\Definition\FieldBuilder;
use Builder\Core\Foundation\Definition\Hook;
use Builder\Core\Foundation\Definition\Section;

it('AccountDefinition::make returns an instance', function (): void {
    $definition = AccountDefinition::make(new AccountProfile);

    expect($definition)->toBeInstanceOf(AccountDefinition::class);
});

it('AccountDefinition has three sections from AccountProfile', function (): void {
    $definition = AccountDefinition::make(new AccountProfile);

    expect($definition->getSections())->toHaveCount(3);
});

it('AccountDefinition sections are sorted by priority', function (): void {
    $definition = AccountDefinition::make(new AccountProfile);
    $priorities = array_map(fn (Section $s) => $s->getPriority(), $definition->getSections());
    $sorted = $priorities;
    sort($sorted);

    expect($priorities)->toEqual($sorted);
});

it('AccountDefinition merges extension sections', function (): void {
    $extension = new class extends AccountExtension
    {
        public function fields(): FieldBuilder
        {
            return FieldBuilder::make()->add(Section::make('extra')->label('Extra')->priority(50));
        }
    };

    $definition = AccountDefinition::make(new AccountProfile, [$extension]);

    expect($definition->getSections())->toHaveCount(4);
    $keys = array_map(fn (Section $s) => $s->getKey(), $definition->getSections());
    expect($keys)->toContain('extra');
});

it('AccountDefinition merges extension hooks', function (): void {
    $extension = new class extends AccountExtension
    {
        public function hooks(): array
        {
            return [Hook::on('saving', function (mixed $user, array $data): void {})];
        }
    };

    $profileHookCount = count((new AccountProfile)->hooks());
    $definition = AccountDefinition::make(new AccountProfile, [$extension]);

    expect($definition->getHooks())->toHaveCount($profileHookCount + 1);
});

it('AccountDefinition toArray includes sections key', function (): void {
    $definition = AccountDefinition::make(new AccountProfile);

    $array = $definition->toArray();
    expect($array)->toHaveKey('sections')
        ->and($array['sections'])->toBeArray()
        ->and($array['sections'])->not->toBeEmpty();
});

it('AccountDefinition extension sections are sorted into correct order', function (): void {
    $extension = new class extends AccountExtension
    {
        public function fields(): FieldBuilder
        {
            return FieldBuilder::make()->add(Section::make('before')->label('Before')->priority(5));
        }
    };

    $definition = AccountDefinition::make(new AccountProfile, [$extension]);
    $priorities = array_map(fn (Section $s) => $s->getPriority(), $definition->getSections());

    // priority 5 should be first
    expect($priorities[0])->toBe(5);
});
