<?php

namespace Apexl\Io\FormBuilder\Components;

use Apexl\Io\Component\Components\Component;
use Apexl\Io\FormBuilder\Interfaces\FormComponent;
use Apexl\Io\FormBuilder\Traits\HasFormChildren;
use Apexl\Io\FormBuilder\Traits\HasFormIdProperty;
use Apexl\Io\Validation\Collections\ValidationRuleCollectionCollection;
use Apexl\Io\Validation\Interfaces\HasValidationRulesInterface;

readonly class FieldsetComponent extends Component implements FormComponent, HasValidationRulesInterface
{
    use HasFormIdProperty;
    use HasFormChildren;

    /**
     * Declared because {@see self::toSchema()} reads `$this->name` directly.
     *
     * `Component` sets the property eagerly only for a class that declares this
     * constant, and otherwise leaves it uninitialised and resolves the default
     * lazily in `toArray()`. `toSchema()` never reaches that, so without this
     * every fieldset fatals on an uninitialised typed property — including the
     * ones `FormBuilder::fieldset()` builds itself.
     *
     * The value is the short name the lazy default would have produced, so
     * nothing downstream sees a different component.
     */
    public final const string NAME = 'FieldsetComponent';

    public function setLegend(string $title): static
    {
        return $this->setProperty('legend', $title);
    }

    public function toSchema(): array
    {
        $this->setProperty('components', $this->components->toArray());
        return [
            '$cmp' => $this->name,
            'props' => $this->props->toArray(),
        ];
    }

    public function getValidationRules(ValidationRuleCollectionCollection $rules): ValidationRuleCollectionCollection
    {
        foreach ($this->components as $component) {
            if ($component instanceof HasValidationRulesInterface) {
                $rules = ValidationRuleCollectionCollection::createFromArray([
                    ...$rules->toArray(),
                    ...$component->getValidationRules($rules)->toArray()
                ]);
            }
        }

        return $rules;
    }
}
