<?php

namespace Components\Ui;

use Components\Base;

class Stars
{
    public static function render($value, $max = 5, array $options = []): string
    {
        $maxStars = max(1, min(20, (int)$max));
        $filledStars = max(0, min($maxStars, (int)$value));

        $size = strtolower(trim((string)($options['size'] ?? 'sm')));
        $sizeClassMap = [
            'xs' => '[&_svg]:size-3!',
            'sm' => '[&_svg]:size-3.5!',
            'md' => '[&_svg]:size-4!',
            'lg' => '[&_svg]:size-5!',
            'xl' => '[&_svg]:size-6!',
        ];

        $sizeClass = trim((string)($options['size_class'] ?? ($sizeClassMap[$size] ?? '[&_svg]:size-3.5!')));
        $wrapperClass = trim('inline-flex items-center gap-1.5 align-middle -translate-y-px ' . (string)($options['wrapper_class'] ?? ''));
        $starsClass = trim('inline-flex items-center gap-0.5 leading-none ' . $sizeClass . ' ' . (string)($options['stars_class'] ?? ''));

        $filledClass = trim((string)($options['filled_class'] ?? 'text-amber-500'));
        $emptyClass = trim((string)($options['empty_class'] ?? 'text-gray-300 dark:text-gray-600'));

        $filledIcon = (string)($options['filled_icon'] ?? Base::SVG_STAR);
        $emptyIcon = (string)($options['empty_icon'] ?? Base::SVG_STAR_OUTLINE);

        $showLabel = array_key_exists('show_label', $options) ? (bool)$options['show_label'] : true;
        $label = isset($options['label']) ? (string)$options['label'] : ($filledStars . '/' . $maxStars);
        $labelClass = trim((string)($options['label_class'] ?? 'text-xs tabular-nums text-secondary dark:text-gray-300'));
        $ariaLabel = isset($options['aria_label']) ? (string)$options['aria_label'] : $label;

        ob_start();
        ?>
        <span <?= Base::attrs(['class' => $wrapperClass, 'role' => 'img', 'aria-label' => $ariaLabel]); ?>>
            <span <?= Base::attrs(['class' => $starsClass, 'aria-hidden' => 'true']); ?>>
                <?php for ($i = 1; $i <= $maxStars; $i++):
                    $isFilled = $i <= $filledStars;
                    ?>
                    <span <?= Base::attrs(['class' => $isFilled ? $filledClass : $emptyClass]); ?>>
                        <?= $isFilled ? $filledIcon : $emptyIcon; ?>
                    </span>
                <?php endfor; ?>
            </span>
            <?php if ($showLabel): ?>
                <span <?= Base::attrs(['class' => $labelClass]); ?>><?= Base::h($label); ?></span>
            <?php endif; ?>
        </span>
        <?php

        return (string)ob_get_clean();
    }
}
