<?php
namespace Components\Ui;

use Components\Base;
use Components\Support\Palette;

/**
 * CollectionIdentity: reusable UI component for a collection list item label (dot + name).
 */
class CollectionIdentity
{
    /**
     * Renders the collection identity span (colored dot or rich icon + name).
     *
     * @param string $name     Escaped collection name HTML (ignored when name_x_text is set).
     * @param mixed  $identity Tailwind class for the dot (string) OR rich identity array:
     *                         ['svg' => ..., 'color' => ..., 'size' => ..., 'variant' => ..., 'shape' => ...]
     * @param array  $options  UI options:
     *   - class:       extra classes appended to the outer span
     *   - base_class:  override the entire outer span base classes
     *   - x_show:      Alpine x-show expression on the outer span
     *   - icon:        Alternative icon HTML (overrides $identity when provided)
     *   - icon_class:  Extra classes for the icon wrapper (replaces auto-generated color classes)
     *   - dot_x_class: Alpine :class binding for the dot (uses dynamic binding instead of static class)
     *   - dot_size_class: Tailwind size utility for the dot (default 'size-2.5')
     *   - name_x_text: Alpine x-text binding; renders name as an empty <span x-text="..."> instead of inline HTML
     *   - secondary_html: Secondary line HTML (escaped before passing in); when set, renders a two-line label.
     *   - secondary_x_text: Alpine x-text binding for the secondary line (ignored when secondary_html is set).
     */
    public static function render(string $name, $identity, array $options = []): string
    {
        $hasSecondary = false;
        if (!empty($options['secondary_html'])) {
            $hasSecondary = true;
        } elseif (!empty($options['secondary_x_text'])) {
            $hasSecondary = true;
        }

        $gap = $options['gap'] ?? 'gap-2';
        $baseClass  = $options['base_class'] ?? ($hasSecondary
                ? 'flex flex-1 min-w-0 items-start ' . $gap
                : 'flex flex-1 min-w-0 items-center ' . $gap . ' truncate');
        $outerClass = $baseClass . (isset($options['class']) ? ' ' . $options['class'] : '');

        $outerAttrs = 'class="' . Base::h($outerClass) . '"';
        if (!empty($options['x_show'])) {
            $outerAttrs .= ' x-show="' . htmlspecialchars((string)$options['x_show'], ENT_QUOTES, 'UTF-8') . '"';
        }

        $richIdentity = is_array($identity) ? $identity : [];
        $icon = $options['icon'] ?? ($richIdentity['svg'] ?? null);

        if ($icon) {
            $iconColor = $options['icon_class'] ?? null;
            $iconSize = isset($options['dot_size_class']) ? trim((string)$options['dot_size_class']) : null;

            if (!empty($richIdentity)) {
                // Rich identity rendering (icon with background)
                $variant = strtolower((string)($richIdentity['variant'] ?? 'tint'));
                $shape = strtolower((string)($richIdentity['shape'] ?? 'round'));
                $colorToken = (string)($richIdentity['color'] ?? 'gray');
                $size = strtolower((string)($richIdentity['size'] ?? ($richIdentity['size_class'] ?? 'md')));

                if ($iconSize === null) {
                    $iconSize = ($size === 'sm' || $size === 'xs') ? 'size-6 p-0.75' : 'size-10 p-2';
                }

                $shapeCls = ($shape === 'square') ? 'rounded-lg' : 'rounded-full';
                $iconBase = 'inline-flex shrink-0 items-center justify-center ' . $shapeCls . ' ' . $iconSize;

                if ($iconColor === null) {
                    $isUtility = $colorToken !== '' && (preg_match('/\b(bg|text|from|to|via|fill|stroke|ring|border)-/i', $colorToken) || strpos($colorToken, ' ') !== false);
                    if ($isUtility) {
                        $iconColor = $colorToken;
                    } elseif ($variant === 'solid') {
                        $bgDot = Palette::dotBg($colorToken, 'gray');
                        $iconColor = trim($bgDot . ' text-white');
                    } else {
                        $iconColor = Palette::classes($colorToken, 'gray');
                    }
                }
                $dotHtml = '<span class="' . $iconBase . ' ' . Base::h($iconColor) . ' [&_svg]:size-full">' . $icon . '</span>';
            } else {
                // Legacy icon rendering (no background) - wrapped in container for alignment
                if ($iconSize === null || $iconSize === 'size-2.5' || $iconSize === '') {
                    $iconSize = 'size-4 [&>svg]:size-4!';
                }

                $identitySize = strtolower((string)($options['size'] ?? 'sm'));
                $containerSize = 'size-6';
                if ($identitySize === 'xs') {
                    $containerSize = 'size-5';
                } elseif ($identitySize === 'lg') {
                    $containerSize = 'size-10';
                }

                $iconContainerBase = 'inline-flex shrink-0 items-center justify-center ' . $containerSize . ($hasSecondary ? ' mt-0.5' : '');

                if ($iconColor === null) {
                    $iconColor = is_string($identity) ? str_replace('bg-', 'text-', $identity) : 'text-gray-400';
                }
                $dotHtml = '<span class="' . $iconContainerBase . '"><span class="inline-flex shrink-0 items-center justify-center ' . $iconSize . ' ' . Base::h($iconColor) . '">' . $icon . '</span></span>';
            }
        } else {
            // Colored dot rendering - wrapped in container for alignment
            $dotSize = isset($options['dot_size_class']) ? trim((string)$options['dot_size_class']) : 'size-2.5';
            if ($dotSize === '') {
                $dotSize = 'size-2.5';
            }

            $identitySize = strtolower((string)($options['size'] ?? 'sm'));
            $containerSize = 'size-6';
            if ($identitySize === 'xs') {
                $containerSize = 'size-5';
            } elseif ($identitySize === '2xs') {
                $containerSize = 'size-4';
            } elseif ($identitySize === 'lg') {
                $containerSize = 'size-10';
            }

            $dotContainerBase = 'inline-flex shrink-0 items-center justify-center ' . $containerSize . ($hasSecondary ? ' mt-1' : '');
            $dotBase = 'block shrink-0 ' . $dotSize . ' rounded-full';

            if (!empty($options['dot_x_class'])) {
                $dotHtml = '<span class="' . $dotContainerBase . '"><span class="' . $dotBase . '" :class="' . htmlspecialchars((string)$options['dot_x_class'], ENT_QUOTES, 'UTF-8') . '"></span></span>';
            } else {
                $dotClass = is_string($identity) ? $identity : 'bg-gray-400';
                $dotHtml = '<span class="' . $dotContainerBase . '"><span class="' . $dotBase . ' ' . Base::h($dotClass) . '"></span></span>';
            }
        }

        if ($hasSecondary) {
            if (!empty($options['name_x_text'])) {
                $primaryHtml = '<span class="block truncate" x-text="' . htmlspecialchars((string)$options['name_x_text'], ENT_QUOTES, 'UTF-8') . '"></span>';
            } else {
                $primaryHtml = '<span class="block truncate">' . $name . '</span>';
            }

            if (!empty($options['secondary_html'])) {
                $secondaryHtml = '<span class="block text-xs text-secondary leading-snug line-clamp-2">' . (string)$options['secondary_html'] . '</span>';
            } elseif (!empty($options['secondary_x_text'])) {
                $secondaryHtml = '<span class="block text-xs text-secondary leading-snug line-clamp-2" x-text="' . htmlspecialchars((string)$options['secondary_x_text'], ENT_QUOTES, 'UTF-8') . '"></span>';
            } else {
                $secondaryHtml = '';
            }

            return '<span ' . $outerAttrs . '>'
                . $dotHtml
                . '<span class="min-w-0 flex-1">'
                . $primaryHtml
                . $secondaryHtml
                . '</span>'
                . '</span>';
        }

        if (!empty($options['name_x_text'])) {
            $nameHtml = '<span class="min-w-0 truncate" x-text="' . htmlspecialchars((string)$options['name_x_text'], ENT_QUOTES, 'UTF-8') . '"></span>';
        } else {
            $nameHtml = '<span class="min-w-0 truncate">' . $name . '</span>';
        }

        return '<span ' . $outerAttrs . '>'
            . $dotHtml
            . $nameHtml
            . '</span>';
    }
}
