<?php

declare(strict_types=1);

namespace App\Framework\Admin\FormFields\Fields;

use App\Framework\Admin\FormFields\Components\FieldWrapper;
use App\Framework\Admin\FormFields\FormField;
use App\Framework\Admin\FormFields\ValueObjects\FieldAttributes;
use App\Framework\Admin\FormFields\ValueObjects\FieldMetadata;
use App\Framework\View\FormBuilder;
use App\Framework\View\ValueObjects\FormElement;

/**
 * Text Input Field
 *
 * Standard text input field using composition
 */
final readonly class TextField implements FormField
{
    public function __construct(
        private FieldMetadata $metadata,
        private FieldAttributes $attributes,
        private FieldWrapper $wrapper,
        private mixed $value = null
    ) {
    }

    public static function create(
        string $name,
        string $label,
        mixed $value = null,
        bool $required = false,
        ?string $placeholder = null,
        ?string $help = null
    ): self {
        return new self(
            metadata: new FieldMetadata($name, $label, $help),
            attributes: new FieldAttributes(
                name: $name,
                id: $name,
                required: $required,
                placeholder: $placeholder
            ),
            wrapper: new FieldWrapper(),
            value: $value
        );
    }

    public function render(FormBuilder $form): FormBuilder
    {
        $attrs = $this->attributes->withAdditional(['type' => 'text']);

        $attrArray = $attrs->toArray();

        if ($this->value !== null && $this->value !== '') {
            $attrArray['value'] = (string) $this->value;
        }

        $input = FormElement::create('input', $attrArray);
        $wrapped = $this->wrapper->wrap($input, $this->metadata);

        return $form->addElement($wrapped);
    }

    public function getName(): string
    {
        return $this->metadata->name;
    }

    public function getValue(): mixed
    {
        return $this->value;
    }

    public function getLabel(): string
    {
        return $this->metadata->label;
    }
}
