<?php

declare(strict_types=1);

namespace App\Framework\View\Functions;

/**
 * LazyComponentFunction
 *
 * Template function for lazy-loaded LiveComponents.
 *
 * Generates placeholder HTML for components that will be loaded
 * when they enter the viewport using IntersectionObserver.
 *
 * Usage in templates:
 * {{ lazy_component('notification-bell:user-123') }}
 * {{ lazy_component('user-stats:456', ['priority' => 'high', 'threshold' => '0.1']) }}
 * {{ lazy_component('feed:latest', ['placeholder' => 'Loading feed...']) }}
 *
 * Options:
 * - priority: 'high' | 'normal' | 'low' (default: 'normal')
 * - threshold: '0.0' to '1.0' (default: '0.1')
 * - placeholder: Custom placeholder text (default: null)
 * - rootMargin: IntersectionObserver root margin (default: null)
 *
 * Generated HTML:
 * <div data-live-component-lazy="component-id"
 *      data-lazy-priority="normal"
 *      data-lazy-threshold="0.1"
 *      data-lazy-placeholder="Loading...">
 * </div>
 */
final readonly class LazyComponentFunction implements TemplateFunction
{
    public function __construct()
    {
        $this->functionName = 'lazy_component';
    }

    /**
     * Generate lazy component placeholder HTML
     *
     * @param string $componentId Component ID (e.g., 'counter:demo')
     * @param array $options Lazy loading options
     * @return string Placeholder HTML
     */
    public function __invoke(string $componentId, array $options = []): string
    {
        // Extract options with defaults
        $priority = $options['priority'] ?? 'normal';
        $threshold = $options['threshold'] ?? '0.1';
        $placeholder = $options['placeholder'] ?? null;
        $rootMargin = $options['rootMargin'] ?? null;
        $class = $options['class'] ?? '';

        // Validate priority
        $validPriorities = ['high', 'normal', 'low'];
        if (! in_array($priority, $validPriorities)) {
            $priority = 'normal';
        }

        // Validate threshold
        $thresholdFloat = (float) $threshold;
        if ($thresholdFloat < 0.0 || $thresholdFloat > 1.0) {
            $threshold = '0.1';
        }

        // Build attributes array
        $attributes = [
            'data-live-component-lazy' => htmlspecialchars($componentId, ENT_QUOTES | ENT_HTML5),
            'data-lazy-priority' => htmlspecialchars($priority, ENT_QUOTES | ENT_HTML5),
            'data-lazy-threshold' => htmlspecialchars($threshold, ENT_QUOTES | ENT_HTML5),
        ];

        // Add optional attributes
        if ($placeholder !== null) {
            $attributes['data-lazy-placeholder'] = htmlspecialchars($placeholder, ENT_QUOTES | ENT_HTML5);
        }

        if ($rootMargin !== null) {
            $attributes['data-lazy-root-margin'] = htmlspecialchars($rootMargin, ENT_QUOTES | ENT_HTML5);
        }

        if (! empty($class)) {
            $attributes['class'] = htmlspecialchars($class, ENT_QUOTES | ENT_HTML5);
        }

        // Convert attributes to HTML string
        $attributesHtml = implode(' ', array_map(
            fn ($key, $value) => sprintf('%s="%s"', $key, $value),
            array_keys($attributes),
            $attributes
        ));

        // Generate placeholder HTML
        return sprintf('<div %s></div>', $attributesHtml);
    }

    public string $functionName;
}
