<?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;

/**
 * Checkbox Field
 *
 * Single checkbox input field using composition
 */
final readonly class CheckboxField implements FormField
{
    public function __construct(
        private FieldMetadata $metadata,
        private FieldAttributes $attributes,
        private FieldWrapper $wrapper,
        private mixed $value = null,
        private string $checkedValue = '1'
    ) {
    }

    public static function create(
        string $name,
        string $label,
        mixed $value = null,
        bool $required = false,
        ?string $help = null,
        string $checkedValue = '1'
    ): self {
        return new self(
            metadata: new FieldMetadata($name, $label, $help),
            attributes: new FieldAttributes(
                name: $name,
                id: $name,
                class: 'form-check-input',
                required: $required
            ),
            wrapper: new FieldWrapper(),
            value: $value,
            checkedValue: $checkedValue
        );
    }

    public function render(FormBuilder $form): FormBuilder
    {
        $attrs = $this->attributes->withAdditional(['type' => 'checkbox', 'value' => $this->checkedValue]);
        $attrArray = $attrs->toArray();

        if ($this->isChecked()) {
            $attrArray['checked'] = 'checked';
        }

        $input = FormElement::create('input', $attrArray);

        $label = FormElement::create(
            'label',
            ['class' => 'form-check-label', 'for' => $this->metadata->name],
            $this->metadata->label
        );

        $checkboxHtml = FormElement::create(
            'div',
            ['class' => 'form-check'],
            $input . $label
        );

        $wrapped = $this->wrapper->wrapWithoutLabel($checkboxHtml, $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;
    }

    private function isChecked(): bool
    {
        if ($this->value === null) {
            return false;
        }

        if (is_bool($this->value)) {
            return $this->value;
        }

        return (string) $this->value === $this->checkedValue;
    }
}
