<?php

namespace Plainwork\Ui\Component\Form;

use Plainwork\Http\Request;
use Plainwork\Ui\Component\AbstractTag;
use Plainwork\Ui\Component\Form\InputInterface;

class Form extends AbstractTag
{
    private $content = null;
    private array $errors = [];
    private array $inputs = [];
    private array $toggle = [];
    private bool $isSubmitted = false;
    private array $buttons = [];
    private array $items = [];
    private array $itemMeta = [];
    private bool $withUpload = false;

    public function withUpload(): self
    {
        $this->withUpload = true;

        return $this;
    }

    public function isWithUpload(): bool
    {
        return $this->withUpload;
    }

    public function setContent($v): self
    {
        $this->content = $v;

        return $this;
    }

    public function getContent()
    {
        return $this->content;
    }

    public function addErrors(array $errors): self
    {
        foreach ($errors as $error) {
            $this->addError($error);
        }

        return $this;
    }

    public function addError($error): self
    {
        $this->errors[] = $error;

        return $this;
    }

    public function getErrors(): array
    {
        return $this->errors;
    }

    public function add(InputInterface $input): self
    {
        return $this->registerInput($input);
    }

    public function registerInput(InputInterface $input): self
    {
        $this->inputs[$input->getName()] = $input;

        return $this;
    }

    public function hasInput(string $name): bool
    {
        return isset($this->inputs[$name]) ? true : false;
    }

    public function input(string $name): ?InputInterface
    {
        return $this->inputs[$name] ?? null;
    }

    public function grab(Request $request): array
    {
        $ret = [];
        if (!$request->isPost()) {
            return $ret;
        }

        $this->isSubmitted = true;
        if ($this->inputs) {
            $inputs = array_filter($this->inputs, fn($e) => !$e->isDisabled());

        // have togglable? remove those that aren't set on
            $togglableInputs = [];
            // $togglableInputs = array_filter($inputs, fn($e) => $this->isItemTogglable($e));
            if ($togglableInputs) {
                $remove = [];
                foreach ($togglableInputs as $e) {
                    $name = $e->getName();
                    $toggler = (new CheckboxInput($name . 'on'));
                    $togglerOn = $toggler->grab($request);
                    if (!$togglerOn) {
                        $remove[] = $name;
                    }
                }
                if ($remove) {
                    $inputs = array_filter($inputs, fn($e) => !in_array($e->getName(), $remove));
                }
            }

            array_walk($inputs, fn($e) => $e->setValue($e->grab($request)));
            $ret = array_map(fn($e) => $e->getValue(), $inputs);
        }

        if (!$ret) {
            $ret = [true];
        }

        return $ret;
    }

    public function isValid(): bool
    {
        if (!$this->isSubmitted) {
            return false;
        }

        if ($this->errors) {
            return false;
        }

        $ret = true;
        foreach ($this->inputs as $input) {
            $errs = $input->getErrors();
            if ($errs) {
                $ret = false;
                break;
            }
        }

        return $ret;
    }

// toggle like this: ->if('input1', 1)->then('input2', false)->then('input3', true)
    public function if(string $inputName, $inputValue): self
    {
        $this->toggle[] = [['name' => $inputName, 'value' => $inputValue]];

        return $this;
    }

    public function then(string $inputName, bool $on)
    {
        $this->toggle[count($this->toggle) - 1][] = ['target' => $inputName, 'on' => $on];

        return $this;
    }

    public function getToggles(): array
    {
        return $this->toggle;
    }
}
