<?php declare(strict_types=1);

namespace Newland\CityTheme\ViewHelpers\CssVariables;

use Neos\FluidAdaptor\Core\ViewHelper\AbstractTagBasedViewHelper;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

/**
 * Viewhelper that converts deep associative array structures into CSS variables where deep keys are separated with
 * a dash (`-`).
 *
 * @example
 * // `colors` being
 * [
 *      'white' => '#ffffff',
 *      'primary' => [
 *          '100' => '#F0FFF4',
 *          '200' => '#C6F6D5',
 *          '300' => '#9AE6B4',
 *          '400' => '#68D391',
 *          '500' => '#48BB78',
 *          '600' => '#38A169',
 *          '700' => '#2F855A',
 *          '800' => '#276749',
 *          '900' => '#22543D',
 *      ]
 * ]
 *
 * // In template:
 * {colors -> cityTheme:cssVariables.renderTag(prefix: 'color', scope: 'html')}
 *
 * // Result:
 * <style>
 *      html {
 *          --color-white:#ffffff;
 *          --color-primary-100:#F0FFF4;
 *          --color-primary-200:#C6F6D5;
 *          --color-primary-300:#9AE6B4;
 *          --color-primary-400:#68D391;
 *          --color-primary-500:#48BB78;
 *          --color-primary-600:#38A169;
 *          --color-primary-700:#2F855A;
 *          --color-primary-800:#276749;
 *          --color-primary-900:#22543D;
 *      }
 * </style>
 */
class RenderTagViewHelper extends AbstractTagBasedViewHelper
{
    protected  $tagName = 'style';

    public function render(array $values = null, string $prefix = null, string $scope = 'html')
    {
        $values = $values ?? $this->renderChildren();
        $variables = [];
        static::appendValue($variables, $values, $prefix);

        $cssLines = [];
        foreach ($variables as $name => $value) {
            $cssLines[] = sprintf('--%s:%s;', $name, $value);
        }

        $this->tag->setContent(sprintf("%s { \n %s \n }", $scope, implode("\n", $cssLines)));
        return $this->tag->render();
    }

    protected static function appendValue(array &$variables, $value, string $key = null): void
    {
        if (is_string($value)) {
            $variables[$key] = $value;
            return;
        }

        if (is_array($value)) {
            foreach ($value as $index => $item) {

                // Special case for keys named `__default__` - they are ignored.
                if (!$key || $index === '__default__') {
                    $prefixedKey = $key;
                } else {
                    $prefixedKey = sprintf('%s-%s', $key, $index);
                }

                static::appendValue($variables, $item, $prefixedKey);
            }
        }
    }

}
