<?php
// components/Ui/TabsGroup.php
namespace Components\Ui;

use Components\Base;

/**
 * TabsGroup
 * Renders a segmented control / grouped button tabs component.
 * Used for Alpine.js driven UI switching.
 */
class TabsGroup extends Base
{
    /**
     * Render the component.
     *
     * @param array $items  List of items: [ ['label' => '...', 'icon' => '...', 'click' => '...', 'active' => '...'], ... ]
     * @param array $opts   Optional: [
     *                          'class' => 'wrapper extra classes',
     *                          'tabClass' => 'base tab classes',
     *                          'activeClass' => 'active tab classes',
     *                          'inactiveClass' => 'inactive tab classes',
     *                          'fullWidth' => bool
     *                      ]
     * @return string
     */
    public static function render(array $items, array $opts = []): string
    {
        if (empty($items)) {
            return '';
        }

        $fullWidth = $opts['fullWidth'] ?? false;
        $model = $opts['model'] ?? null;
        $size = $opts['size'] ?? 'md';

        $sizeMap = [
            'xs' => [
                'wrapper' => 'p-0.75 gap-0.5 rounded-md',
                'tab' => 'px-2 py-0.5 text-xs rounded-sm',
                'icon' => '[&_svg]:size-3 [&>img]:size-3',
                'gap' => 'gap-1'
            ],
            'sm' => [
                'wrapper' => 'p-1 gap-0.5 rounded-lg',
                'tab' => 'px-2.5 py-1 text-sm rounded-md',
                'icon' => '[&_svg]:size-4 [&>img]:size-4',
                'gap' => 'gap-1.5'
            ],
            'md' => [
                'wrapper' => 'p-1.5 gap-1 rounded-lg',
                'tab' => 'px-3 py-1 text-sm rounded-md',
                'icon' => '[&_svg]:size-4 [&>img]:size-4',
                'gap' => 'gap-1.5'
            ]
        ];
        $sizeStyles = $sizeMap[$size] ?? $sizeMap['md'];

        // Default classes from ScheduleConfig.php
        $wrapperBase = 'flex flex-nowrap bg-gray-100 dark:bg-gray-800/60 min-w-0 relative ' . $sizeStyles['wrapper'];
        if ($fullWidth) {
            $wrapperBase .= ' w-full';
        }
        $wrapperClass = trim($wrapperBase . ' ' . ($opts['class'] ?? ''));

        $tabBase = $opts['tabClass'] ?? $sizeStyles['tab'] . " relative font-medium cursor-pointer transition-all duration-150 focus:outline-none truncate";
        if (isset($opts['tabClass']) && !str_contains($tabBase, 'relative')) {
            $tabBase .= ' relative';
        }
        if ($fullWidth && !isset($opts['tabClass'])) {
            $tabBase .= ' flex-1 text-center';
        }
        $tabActive = $opts['activeClass'] ?? "bg-white text-gray-900 dark:bg-gray-600 dark:text-white";
        $tabInactive = $opts['inactiveClass'] ?? "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200";

        // Sliding Highlight Alpine Logic
        $syncJs = "let active = this.\$el.querySelector('[data-active=true]'); if (active && active.offsetWidth > 0) { this.hWidth = active.offsetWidth + 'px'; this.hLeft = active.offsetLeft + 'px'; this.hTop = active.offsetTop + 'px'; this.hHeight = active.offsetHeight + 'px'; }";
        $xData = "{ hWidth: '0px', hLeft: '0px', hTop: '0px', hHeight: '0px', animating: false, sync() { $syncJs } }";
        $xInit = "\$nextTick(() => { sync(); setTimeout(() => { sync(); animating = true; }, 100); setTimeout(() => { sync(); }, 400); });";
        if ($model) {
            $xInit .= " \$watch(() => { try { return $model; } catch(e) { return undefined; } }, () => \$nextTick(() => sync()));";
        }

        // Highlight element
        $rounding = 'rounded-md';
        if (str_contains($tabBase, 'rounded-sm')) $rounding = 'rounded-sm';
        if (str_contains($tabBase, 'rounded-lg')) $rounding = 'rounded-lg';

        $highlightHtml = <<<HTML
    <div class="absolute bg-white dark:bg-gray-600 {$rounding} transition-all duration-100 ease-out"
    :class="{'hidden' : !animating}"
         :style="{ width: hWidth, left: hLeft, top: hTop, height: hHeight }"
         x-cloak>
    </div>
HTML;

        $buttonsHtml = '';
        foreach ($items as $item) {
            $label = $item['label'] ?? '';
            $value = $item['value'] ?? null;
            $icon = $item['icon'] ?? null;

            if ($model && $value !== null) {
                $valJs = json_encode((string)$value, JSON_UNESCAPED_UNICODE);
                $click = "(function() { try { {$model} = {$valJs} } catch(e) {}";
                if (isset($item['click']) && $item['click'] !== '') {
                    $click .= "; " . $item['click'];
                }
                $click .= " })()";
                $active = "((function() { try { return {$model} === {$valJs}; } catch(e) { return false; } })())";
            } else {
                $click = $item['click'] ?? '';
                $active = $item['active'] ?? 'false';
            }

            $attrs = $item['attrs'] ?? [];
            $itemClass = trim(($item['class'] ?? '') . ' ' . ($attrs['class'] ?? ''));
            if ($icon) {
                $itemClass .= ' flex items-center justify-center ' . $sizeStyles['gap'];
            }
            unset($attrs['class']);

            // When using sliding highlight with default activeClass, we want to remove the bg from the button
            // so only the highlight provides the background.
            $btnActiveClasses = $tabActive;
            if (!isset($opts['activeClass'])) {
                $btnActiveClasses = "text-gray-900 dark:text-white";
            }

            $clickJs = trim((string)$click);
            $clickJs = rtrim($clickJs, "; \t\n\r\0\x0B");
            $clickHandler = ($clickJs !== '')
                ? $clickJs . "; \$nextTick(() => sync())"
                : "\$nextTick(() => sync())";

            $btnAttrs = array_merge([
                'type' => 'button',
                '@click' => $clickHandler,
                ':class' => "($active) ? '$btnActiveClasses' : '$tabInactive'",
                ':data-active' => "($active) ? 'true' : 'false'",
                'class' => trim($tabBase . ' ' . $itemClass)
            ], $attrs);

            if ($model && isset($opts['attrs'])) {
                // Merge wrapper level attrs into each button if needed, 
                // but usually we want to merge them into the wrapper.
                // Wait, I passed @click in opts['attrs'] in my calls.
            }

            $attrStr = self::attrs($btnAttrs);
            $content = self::h($label);

            if ($icon) {
                $content = "<span class='shrink-0 {$sizeStyles['icon']}'>{$icon}</span><span class='truncate'>{$content}</span>";
            }

            $buttonsHtml .= <<<HTML
<button {$attrStr}>{$content}</button>
HTML;
        }

        $wrapperAttrs = $opts['attrs'] ?? [];
        $wrapperAttrs['class'] = $wrapperClass;
        $wrapperAttrs['x-data'] = $xData;
        $wrapperAttrs['x-init'] = $xInit;
        $wrapperAttrs['@resize.window.debounce.150'] = 'sync()';
        $attrStrWrapper = self::attrs($wrapperAttrs);

        return <<<HTML
<div {$attrStrWrapper}>
    {$highlightHtml}
    {$buttonsHtml}
</div>
HTML;
    }
}
