<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Account;

use Builder\Core\Foundation\Definition\Hook;
use Builder\Core\Foundation\Definition\Section;

final class AccountDefinition
{
    /**
     * @param  list<Section>  $sections
     * @param  array<string, mixed>  $rules
     * @param  list<Hook>  $hooks
     */
    private function __construct(
        private readonly array $sections,
        private readonly array $rules,
        private readonly array $hooks,
    ) {}

    /**
     * @param  list<AccountExtension>  $extensions
     */
    public static function make(AccountProfileDefinition $profile, array $extensions = []): self
    {
        $sections = $profile->fields()->toSections();
        $rules = $profile->rules();
        $hooks = $profile->hooks();

        foreach ($extensions as $extension) {
            $sections = array_merge($sections, $extension->fields()->toSections());
            $rules = array_merge($rules, $extension->rules());
            $hooks = array_merge($hooks, $extension->hooks());
        }

        usort($sections, fn (Section $a, Section $b): int => $a->getPriority() <=> $b->getPriority());

        return new self(
            sections: $sections,
            rules: $rules,
            hooks: $hooks,
        );
    }

    /** @return list<Section> */
    public function getSections(): array
    {
        return $this->sections;
    }

    /** @return array<string, mixed> */
    public function getRules(): array
    {
        return $this->rules;
    }

    /** @return list<Hook> */
    public function getHooks(): array
    {
        return $this->hooks;
    }

    /** @return array<string, mixed> */
    public function toArray(): array
    {
        return [
            'sections' => array_map(fn (Section $s): array => $s->toArray(), $this->sections),
        ];
    }
}
