<?php

declare(strict_types=1);

final class MyronTokenControlRenderer
{
    /**
     * @param list<string> $options
     */
    public function render(string $name, string $value, string $controlType, string $cssVar, array $options = []): string
    {
        $controlType = trim($controlType) !== '' ? trim($controlType) : 'text';
        $nameEsc = $this->escape($name);
        $valueEsc = $this->escape($value);
        $cssVarEsc = $this->escape($cssVar);

        return match ($controlType) {
            'color' => '<input class="sg-field__control" type="text" name="' . $nameEsc . '" value="' . $valueEsc . '" placeholder="#000000 or var(--myron-...)">',
            'opacity' => '<input class="sg-field__control" type="range" min="0" max="1" step="0.05" name="' . $nameEsc . '" value="' . ($valueEsc !== '' ? $valueEsc : '1') . '">',
            'lengthPx' => '<input class="sg-field__control" type="number" step="1" min="0" name="' . $nameEsc . '" value="' . $this->escape($this->stripPx($value)) . '" data-token-unit="px">',
            'scale' => $this->select($name, $value, $options !== [] ? $options : ['0', '0.25rem', '0.5rem', '0.75rem', '1rem', '1.5rem', '2rem', '3rem']),
            'fontRole' => $this->select($name, $value, $options !== [] ? $options : ['var(--myron-typography-font-sans)', 'var(--myron-typography-font-serif)', 'var(--myron-typography-font-mono)']),
            'enum' => $this->select($name, $value, $options),
            default => '<input class="sg-field__control" type="text" name="' . $nameEsc . '" value="' . $valueEsc . '" data-token-control="' . $this->escape($controlType) . '" data-token-name="' . $cssVarEsc . '">',
        };
    }

    public function controlTypeForToken(string $cssVar): string
    {
        $cssVar = trim($cssVar);
        if (str_contains($cssVar, 'color')) {
            return 'color';
        }
        if (str_contains($cssVar, 'opacity')) {
            return 'opacity';
        }
        if (str_contains($cssVar, 'font')) {
            return 'fontRole';
        }
        if (str_contains($cssVar, 'space') || str_contains($cssVar, 'size')) {
            return 'scale';
        }
        if (str_contains($cssVar, 'radius') || str_contains($cssVar, 'border')) {
            return 'lengthPx';
        }

        return 'text';
    }

    /**
     * @param list<string> $options
     */
    private function select(string $name, string $value, array $options): string
    {
        $html = '<select class="sg-field__control" name="' . $this->escape($name) . '">';
        $html .= '<option value="">Inherit</option>';
        foreach ($options as $option) {
            $option = trim((string) $option);
            if ($option === '') {
                continue;
            }
            $selected = $option === $value ? ' selected' : '';
            $html .= '<option value="' . $this->escape($option) . '"' . $selected . '>' . $this->escape($option) . '</option>';
        }
        $html .= '</select>';

        return $html;
    }

    private function stripPx(string $value): string
    {
        $value = trim($value);
        return str_ends_with($value, 'px') ? substr($value, 0, -2) : $value;
    }

    private function escape(string $value): string
    {
        return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
    }
}
