<script lang="ts">
    import X from '@lucide/svelte/icons/x';

    type Variant = 'neutral' | 'primary' | 'soft';

    let {
        label,
        href,
        variant = 'neutral',
        onRemove,
        removeLabel = 'Remove',
        testid
    }: {
        label: string;
        href?: string;
        variant?: Variant;
        onRemove?: () => void;
        removeLabel?: string;
        testid?: string;
    } = $props();
</script>

{#if href}
    <a class="chip {variant}" {href} data-testid={testid}>
        <span class="chip-label">{label}</span>
        {#if onRemove}
            <button
                type="button"
                class="chip-remove"
                aria-label={removeLabel}
                title={removeLabel}
                onclick={(e) => {
                    e.preventDefault();
                    onRemove?.();
                }}
            >
                <X size={12} aria-hidden="true" />
            </button>
        {/if}
    </a>
{:else}
    <span class="chip {variant}" data-testid={testid}>
        <span class="chip-label">{label}</span>
        {#if onRemove}
            <button
                type="button"
                class="chip-remove"
                aria-label={removeLabel}
                title={removeLabel}
                onclick={() => onRemove?.()}
            >
                <X size={12} aria-hidden="true" />
            </button>
        {/if}
    </span>
{/if}

<style>
    .chip {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        padding: 2px var(--space-2);
        border-radius: var(--radius-pill);
        font-size: var(--font-xs);
        font-weight: var(--weight-medium);
        line-height: var(--leading-tight);
        background: var(--surface-elevated);
        border: 1px solid var(--border);
        color: var(--text);
        text-decoration: none;
        /* Cap the chip at its row width so a long author handle or
           tag slug doesn't push past the chip-row's edge. min-width: 0
           is the flex-item escape so it can actually shrink. */
        max-width: 100%;
        min-width: 0;
    }

    a.chip:hover {
        background: var(--primary-soft-bg);
        border-color: var(--primary);
        color: var(--text);
        text-decoration: none;
    }

    .chip.primary {
        background: var(--primary-soft-bg);
        border-color: var(--primary);
    }

    .chip.soft {
        background: transparent;
        border-color: var(--border-strong);
        color: var(--text-muted);
    }

    .chip-label {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        /* `anywhere` lets a no-space token (a romanized title, a tag
           slug) break before it ellipsizes — keeps the chip inside
           its row even when the label has no soft-break points. */
        overflow-wrap: anywhere;
    }

    .chip-remove {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 16px;
        height: 16px;
        padding: 0;
        background: transparent;
        border: 0;
        color: inherit;
        opacity: 0.6;
        cursor: pointer;
        border-radius: var(--radius-pill);
    }

    .chip-remove:hover {
        opacity: 1;
        background: var(--danger-soft-bg);
        color: var(--danger);
    }

    /* On touch the 16px glyph is far below the tap floor. Rather than grow
       the chip (which would inflate every tag row), overlay an invisible,
       centered hit area sized to --tap-min — the glyph stays compact while
       the tappable region reaches a comfortable size. */
    @media (max-width: 640px) {
        .chip-remove {
            position: relative;
        }

        .chip-remove::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            min-width: var(--tap-min);
            min-height: var(--tap-min);
        }
    }
</style>
