<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Definition;

use Builder\Core\Support\Module;
use Illuminate\Support\Traits\Conditionable;

final class FieldBuilder
{
    use Conditionable;

    /** @var list<Section|Field> */
    private array $items = [];

    public static function make(): self
    {
        return new self;
    }

    /**
     * Add items only when the given module is loaded.
     *
     * @param  callable(self): self  $callback
     */
    public function whenModule(string $key, callable $callback): self
    {
        return $this->when(Module::has($key), $callback);
    }

    public function add(Section|Field ...$items): self
    {
        foreach ($items as $item) {
            $this->items[] = $item;
        }

        return $this;
    }

    /**
     * Resolves all items into sections.
     * Bare Fields are grouped into a hidden '_fields' section.
     *
     * @return list<Section>
     */
    public function toSections(): array
    {
        $sections = [];
        $bareFields = [];

        foreach ($this->items as $item) {
            if ($item instanceof Section) {
                if ($bareFields !== []) {
                    $sections[] = Section::make('_fields')->label('')->fields($bareFields);
                    $bareFields = [];
                }

                $sections[] = $item;
            } else {
                $bareFields[] = $item;
            }
        }

        if ($bareFields !== []) {
            $sections[] = Section::make('_fields')->label('')->fields($bareFields);
        }

        return $sections;
    }

    /**
     * Extracts all Fields, flattening any sections.
     * Used by Block handlers which work with flat field lists.
     *
     * @return list<Field>
     */
    public function toFields(): array
    {
        $fields = [];

        foreach ($this->items as $item) {
            if ($item instanceof Field) {
                $fields[] = $item;
            } elseif ($item instanceof Section) {
                foreach ($item->getFields() as $field) {
                    $fields[] = $field;
                }
            }
        }

        return $fields;
    }
}
