<?php

namespace apexl\Io\modules\formbuilder\Components\FormKitField;

use apexl\Io\modules\component\Collections\ComponentCollection;
use apexl\Io\modules\component\Collections\ComponentPropertyCollection;
use apexl\Io\modules\component\Component\Component;
use apexl\Io\modules\component\Factories\ComponentPropertyFactory;
use apexl\Io\modules\formbuilder\Collections\FormKitValidationCollection;
use apexl\Io\modules\formbuilder\FormKitValidation\FormKitValidation;
use apexl\Io\modules\formbuilder\Interfaces\FormComponent;
use apexl\Io\modules\formbuilder\Traits\HasFormIdProperty;
use Arrayy\Type\StringCollection;

abstract readonly class FormKitField extends Component implements FormComponent
{
    use HasFormIdProperty;

    protected const string TYPE = self::TYPE;
    protected FormKitValidationCollection $validations;

    public function __construct(
        string $fieldName,
        ComponentPropertyFactory $propertyFactory,
        ComponentPropertyCollection $props,
        ComponentCollection $components,
        StringCollection $classes,
    ) {
        parent::__construct(
            $propertyFactory,
            $props,
            $components,
            $classes,
            'FormKit',
            $fieldName,
        );

        $this->setName($fieldName);
        $this->setType(static::TYPE);
        $this->validations = new FormKitValidationCollection();
    }

    public function setName(string $fieldName): static
    {
        $this->setProperty('name', $fieldName);

        if (!$this->hasProperty('id')) {
            $this->setId($fieldName);
        }

        return $this;
    }

    public function setId(string $id): static
    {
        return $this->setProperty('id', $id);
    }

    private function setType(string $type): static
    {
        return $this->setProperty('type', $type);
    }

    public function setLabel(string $label): static
    {
        return $this->setProperty('label', $label);
    }

    public function isRequired(): static
    {
        $this->addValidation(FormKitValidation::required());

        return $this;
    }

    public function addValidation(FormKitValidation|string $validation, string $config = ''): static
    {
        if (!$validation instanceof FormKitValidation) {
            $validation = FormKitValidation::create($validation, $config);
        }

        $this->validations->set($validation->name, $validation);

        return $this;
    }

    public function isDisabled(bool $isDisabled = true): static
    {
        return $this->setProperty('disabled', $isDisabled);
    }

    public function hideLabel(): static
    {
        return $this->setProperty('label-class', 'visually-hidden');
    }

    public function setHelp(string $help): static
    {
        return $this->setProperty('help', $help);
    }

    public function toSchema(): array
    {
        $this->setProperty('validation', $this->validations->toString());

        return [
            '$formkit' => static::TYPE,
            ...$this->props,
        ];
    }
}
