<?php
namespace Components\Ui;

use Components\Button;
use Components\Router;
use Components\Base;

/**
 * FlowHelpers: reusable UI elements for Flow visualization cards.
 */
class FlowHelpers
{
    /**
     * Returns the Alpine.js data object string for flow scroll containers.
     * Expects $refs.scroller to be the scrollable element.
     */
    public static function alpineData(string $behavior = 'smooth'): string
    {
        return '{
            canScrollX: false,
            atStart: true,
            atEnd: false,
            refreshing: false,
            init() {
                this.update();
                if (window.IntersectionObserver) {
                    const observer = new IntersectionObserver(() => {
                        this.update();
                    }, { threshold: [0, 1] });
                    observer.observe(this.$el);
                }
            },
            update() {
                const el = this.$refs.scroller || this.$el;
                if (!el) return;
                this.canScrollX = el.scrollWidth > (el.clientWidth + 2);
                const max = Math.max(0, el.scrollWidth - el.clientWidth);
                this.atStart = el.scrollLeft <= 1;
                this.atEnd = el.scrollLeft >= (max - 1);
            },
            scrollBy(dx) {
                const el = this.$refs.scroller || this.$el;
                if (!el) return;
                el.scrollBy({ left: dx, behavior: \'' . $behavior . '\' });
            }
        }';
    }

    /**
     * Renders a single scroll button.
     */
    public static function renderScrollButton(string $direction, int $amount = 280, string $class = ''): string
    {
        $dx = ($direction === 'left' ? -$amount : $amount);
        $icon = ($direction === 'left'
            ? '<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />'
            : '<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />');

        ob_start();
        ?>
        <button type="button" @click.stop="scrollBy(<?= $dx ?>)"
                class="pointer-events-auto inline-flex items-center justify-center shrink-0 <?= $class ?>"
                x-cloak x-show="canScrollX && <?= $direction === 'left' ? '!atStart' : '!atEnd' ?>" x-transition.opacity>
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="size-5">
                <?= $icon ?>
            </svg>
        </button>
        <?php
        return ob_get_clean();
    }

    /**
     * Renders the "Refresh Flow" button that triggers invalidate_flow_cache.
     */
    public static function renderRefreshButton(string $type, int $id = 0, string $eventPrefix = ''): string
    {
        $refreshUrl = Router::url('invalidate_flow_cache', [
            'partial' => 1,
            'id' => $id,
            'type' => $type,
            'event_prefix' => $eventPrefix,
        ]);
        ob_start();
        ?>
        <div class="absolute top-0 right-1 z-30">
            <?php
            echo Button::render('', [
                'size' => 'xs',
                'variant' => 'ghost',
                'icon' => '<span class="when-idle p-0.5 [&_svg]:size-4">' . Base::SVG_REFRESH . '</span><span class="when-request hidden p-0.5 [&_svg]:size-4">' . Base::SVG_SPINNER . '</span>',
                'class' => 'opacity-30 text-secondary/30 hover:text-secondary [&.htmx-request_.when-idle]:hidden [&.htmx-request_.when-request]:inline-flex disabled:opacity-50 ',
                'attrs' => [
                    'hx-post' => $refreshUrl,
                    'hx-swap' => 'none',
                    'hx-indicator' => '#' . ('refresh-btn-' . substr(md5($type . '|' . (string)$id . '|' . $eventPrefix), 0, 8)),
                    'hx-disabled-elt' => '#' . ('refresh-btn-' . substr(md5($type . '|' . (string)$id . '|' . $eventPrefix), 0, 8)),
                    ':disabled' => 'refreshing',
                    'data-no-global-loader' => '1',
                    'title' => 'Refresh Flow',
                    'id' => 'refresh-btn-' . substr(md5($type . '|' . (string)$id . '|' . $eventPrefix), 0, 8),
                ],
            ]);
            ?>
        </div>
        <?php
        return ob_get_clean();
    }

    /**
     * Renders horizontal scroll hint overlays (chevrons).
     * Expects Alpine data from alpineData().
     */
    public static function renderScrollHints(): string
    {
        ob_start();
        ?>
        <!-- Horizontal scroll hint overlays (fixed within the area) -->
        <div x-cloak x-show="canScrollX && !atStart" x-transition.opacity
             class="pointer-events-none absolute inset-y-0 left-0 flex items-center z-20">
            <button type="button" @click.stop="scrollBy(-280)"
                    class="pointer-events-auto inline-flex items-center justify-center w-6 h-full bg-secondary/20 text-white shadow-sm ring-1 ring-white/20 hover:bg-secondary/30 focus:outline-none">
                <!-- left chevron -->
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
                </svg>
            </button>
        </div>
        <div x-cloak x-show="canScrollX && !atEnd" x-transition.opacity
             class="pointer-events-none absolute inset-y-0 right-0 flex items-center z-20">
            <button type="button" @click.stop="scrollBy(280)"
                    class="pointer-events-auto inline-flex items-center justify-center w-6 h-full bg-secondary/20 text-white shadow-sm ring-1 ring-white/20 hover:bg-secondary/30 focus:outline-none">
                <!-- right chevron -->
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
                    <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
                </svg>
            </button>
        </div>
        <?php
        return ob_get_clean();
    }
}
