<?php
namespace Components\Ui;

use Components\Button;

/**
 * ExpandControls: renders "Expand all" / "Collapse all" buttons for Alpine lists with openMap.
 * All inline HTML is captured with output buffering and returned as a string.
 *
 * Options:
 * - all_open_init: bool — initial state to avoid flicker (hides Expand button if already all open)
 * - all_closed_init: bool — initial state to avoid flicker (hides Collapse button if already all closed)
 * - expand_label: string (default: 'Expand all')
 * - collapse_label: string (default: 'Collapse all')
 * - expand_attrs: array — extra attributes for Expand button (merged)
 * - collapse_attrs: array — extra attributes for Collapse button (merged)
 * - icon_only: bool — render icon-only controls (default: true).
 *   - In icon-only mode a single toggle button is rendered:
 *     - when all closed → clicking expands all (shows expand icon)
 *     - when not all closed → clicking collapses all (shows collapse icon)
 *   - When false, renders two text buttons (legacy behavior).
 */
class ExpandControls
{
    public static function render(array $options = []): string
    {
        $allOpenInit = (bool)($options['all_open_init'] ?? false);
        $allClosedInit = (bool)($options['all_closed_init'] ?? false);
        $expandLabel = (string)($options['expand_label'] ?? \mh_lng('UI_EXPAND_ALL', 'Expand all'));
        $collapseLabel = (string)($options['collapse_label'] ?? \mh_lng('UI_COLLAPSE_ALL', 'Collapse all'));
        $expandAttrs = is_array($options['expand_attrs'] ?? null) ? $options['expand_attrs'] : [];
        $collapseAttrs = is_array($options['collapse_attrs'] ?? null) ? $options['collapse_attrs'] : [];
        $iconOnly = (bool)($options['icon_only'] ?? true);

        // Icon-only mode can be scoped by providing a custom expression and actions.
        // This is important for grouped lists where expand/collapse should only affect the current group.
        $allClosedExpr = (string)($options['all_closed_expr'] ?? 'allClosed()');
        $expandAction = (string)($options['expand_action'] ?? 'expandAll()');
        $collapseAction = (string)($options['collapse_action'] ?? 'collapseAll()');
        $toggleAttrs = is_array($options['toggle_attrs'] ?? null) ? $options['toggle_attrs'] : [];

        // Defaults aligned with trigger_layout_list (used by the text variant)
        $expandAttrs = array_replace([
            '@click' => 'expandAll()',
            'data-no-global-loader' => '1',
            'x-show' => '!allOpen()',
            'x-cloak' => true,
            'style' => ($allOpenInit ? 'display:none' : null),
        ], $expandAttrs);
        $collapseAttrs = array_replace([
            '@click' => 'collapseAll()',
            'data-no-global-loader' => '1',
            'x-show' => '!allClosed()',
            'x-cloak' => true,
            'style' => ($allClosedInit ? 'display:none' : null),
        ], $collapseAttrs);

        // Add hover titles in icon mode for the text variant buttons as well (can be overridden by passed attrs)
        if ($iconOnly) {
            if (!isset($expandAttrs['title'])) {
                $expandAttrs['title'] = $expandLabel;
            }
            if (!isset($collapseAttrs['title'])) {
                $collapseAttrs['title'] = $collapseLabel;
            }
        }

        $wrapperClass = (string)($options['wrapper_class'] ?? 'flex items-center justify-end gap-2 mb-3');

        // Prepare icon-only, single-toggle button
        if ($iconOnly) {
            // Dynamic title for the single button
            $expandLabelJs = json_encode($expandLabel);
            $collapseLabelJs = json_encode($collapseLabel);

            $toggleAttrs = array_replace([
                '@click' => "{$allClosedExpr} ? {$expandAction} : {$collapseAction}",
                'data-no-global-loader' => '1',
                'x-bind:title' => "{$allClosedExpr} ? {$expandLabelJs} : {$collapseLabelJs}",
            ], $toggleAttrs);

            // Build icon HTML: show expand icon when all are closed, else show collapse icon
            $expandIconStyle = $allClosedInit ? null : ' style="display:none"';
            $collapseIconStyle = $allClosedInit ? ' style="display:none"' : null;

            $allClosedExprAttr = htmlspecialchars($allClosedExpr, ENT_QUOTES, 'UTF-8');
            $notAllClosedExprAttr = htmlspecialchars('!(' . $allClosedExpr . ')', ENT_QUOTES, 'UTF-8');
            $iconHtml =
                '<span x-cloak x-show="' . $allClosedExprAttr . '" title="' . \Components\Base::h($expandLabel) . '"' . ($expandIconStyle ?? '') . '>' . \Components\Base::SVG_LIST_CHEVRON_UP_DOWN . '</span>' .
                '<span x-show="' . $notAllClosedExprAttr . '" title="' . \Components\Base::h($collapseLabel) . '"' . ($collapseIconStyle ?? '') . '>' . \Components\Base::SVG_LIST_CHEVRON_DOWN_UP . '</span>';
        }

        ob_start();
        ?>
        <div class="<?= htmlspecialchars($wrapperClass, ENT_QUOTES, 'UTF-8'); ?>">
            <?php
            if ($iconOnly) {
                echo Button::render('', [
                    'size' => 'md',
                    'variant' => 'ghost',
                    'icon' => $iconHtml,
                    'attrs' => $toggleAttrs,
                ]);
            } else {
                echo Button::render($expandLabel, [ 'size' => 'sm', 'variant' => 'ghost', 'attrs' => $expandAttrs ]);
                echo Button::render($collapseLabel, [ 'size' => 'sm', 'variant' => 'ghost', 'attrs' => $collapseAttrs ]);
            }
            ?>
        </div>
        <?php
        return ob_get_clean();
    }
}
