<?php

declare(strict_types=1);

namespace AC\Form\Element;

use AC\Form\Element;

class Checkbox extends Element
{
    protected ?bool $vertical = null;

    protected ?bool $multiple = null;

    protected ?bool $disabled = null;

    protected function get_type(): string
    {
        return 'checkbox';
    }

    protected function get_classes(): array
    {
        $classes = [
            $this->get_type() . '-labels',
        ];

        if ($this->is_vertical()) {
            $classes[] = 'vertical';
        }

        return $classes;
    }

    public function render(): string
    {
        $elements = $this->get_elements();

        if (! $elements) {
            return '';
        }

        $template = '<div class="%s">%s</div>';

        return sprintf($template, implode(' ', $this->get_classes()), implode("\n", $elements));
    }

    private function get_elements(): ?array
    {
        if ($this->is_multiple()) {
            $this->set_name($this->get_name() . '[]');
        }

        $options = $this->get_options();

        if (empty($options)) {
            return null;
        }

        $elements = [];

        $value = (array)$this->get_value();

        foreach ($options as $key => $label) {
            $input = new Input((string)$this->get_name());

            $input
                ->set_value($key)
                ->set_type($this->get_type())
                ->set_id($this->get_id() . '-' . $key);

            if (in_array($key, $value, true)) {
                $input->set_attribute('checked', 'checked');
            }

            if ($this->disabled) {
                $input->set_attribute('disabled', 'disabled');
            }

            $attributes = $this->get_attributes();

            $elements[] = sprintf(
                '<label %s>%s%s</label>',
                $this->get_attributes_as_string($attributes),
                $input->render(),
                esc_html($label)
            );
        }

        if ($description = $this->render_description()) {
            $elements[] = $description;
        }

        return $elements;
    }

    public function set_multiple(bool $multiple): self
    {
        $this->multiple = $multiple;

        return $this;
    }

    public function is_multiple(): bool
    {
        if (empty($this->multiple)) {
            return false;
        }

        return $this->multiple;
    }

    public function set_vertical(bool $vertical): self
    {
        $this->vertical = $vertical;

        return $this;
    }

    public function is_vertical(): bool
    {
        if (empty($this->vertical)) {
            return false;
        }

        return $this->vertical;
    }

    public function set_disabled(bool $disabled): self
    {
        $this->disabled = $disabled;

        return $this;
    }

}
