<?php


namespace App\View;

/**
 * Widget
 *
 * @property-read string $name
 * @property-read string $id
 * @property-read string $label
 * @property-read string $prepend
 * @property-read string $append
 * @property-read string|null $help
 * @property-read string|null $value
 * @property-read string $attributes
 * @property-read int $labelCols
 * @property-read int $fieldCols
 */
class Widget
{
    protected $attributesArray = [],
        $id, $name, $label, $value,
        $viewName, // view to use inside the form namespace
        $help, // help button with tooltip
        $prepend, $append, // input-group (add-ons)
        $labelCols, $fieldCols, // grid layout setting (label/field cols)
        $styleArray = [];

    public function __construct($viewName, $name, $label)
    {
        $this->id = 'field-'.$name;
        $this->name = $name;
        $this->label = $label;
        $this->viewName = $viewName;
    }

    // setting attributes via magic method
    public function __call($method, $args)
    {
        static $cssProps = [
            'height', 'minHeight', 'maxHeight'
        ];

        if (empty($args)) $args = [null];

        $arg = $args[0];

        // css
        $lccamel = $method;
        if (in_array($lccamel, $cssProps)) {
            return $this->css(kebab_case($lccamel), $arg);
        }

        if (property_exists($this, $method)) {
            $this->$method = $arg;
        }
        else {
            $this->attributesArray[kebab_case($method)] = $arg;
        }

        return $this;
    }

    /** Explicitly set a CSS rule */
    public function css($prop, $val)
    {
        $this->styleArray[$prop] = $val;
        return $this;
    }

    /** Explicitly set an attribute */
    public function attr($attr, $val)
    {
        $this->attributesArray[$attr] = $val;
        return $this;
    }

    /** Configure a text field for automatic alias generation */
    public function autoAlias($targetName, $delimiter='_')
    {
        return $this->attr('data-autoalias', $targetName)->attr('data-aa-delimiter', $delimiter);
    }

    /** Apply a given layout (bootstrap grid, 12 cols total) */
    public function layout($labelCols, $fieldCols)
    {
        $this->labelCols = $labelCols;
        $this->fieldCols = $fieldCols;
        return $this;
    }

    public function __get($name)
    {
        if ($name == 'attributes') {
            return $this->compileAttribs();
        }

        if ($name == 'value') {
            return old($this->name, $this->value);
        }

        if (property_exists($this, $name)) {
            return $this->$name;
        }

        return null;
    }

    public function compileAttribs()
    {
        // compile attribs string
        $attribs_s = array_reduce(array_keys($this->attributesArray), function ($carry, $key) {
            if ($this->attributesArray[$key] === null) {
                // simple attribs like 'required'
                return $carry . ' ' . $key;
            } else {
                return $carry . ' ' . $key . '="' . e($this->attributesArray[$key]) . '"';
            }
        }, '');

        // add a compiled list of styles
        if (!empty($this->styleArray)) {
            $attribs_s .= ' style="'.trim(e(array_reduce(array_keys($this->styleArray), function ($carry, $key) {
                return $carry . $key . ': ' . $this->styleArray[$key] . '; ';
            }, ''))).'"';
        }

        return trim($attribs_s);
    }

    public function render()
    {
        return view('form.'.$this->viewName)->with(['w' => $this]);
    }

    public function __toString()
    {
        return (string) $this->render();
    }
}