<!--
    Component: FontListItem
    Displays a font item with a checkbox and its characteristics in badges.
-->
<script lang="ts">
import { Badge } from '$shared/shadcn/ui/badge';
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { Spring } from 'svelte/motion';
import {
    type UnifiedFont,
    selectedFontsStore,
} from '../../model';
import FontApplicator from '../FontApplicator/FontApplicator.svelte';

interface Props {
    /**
     * Object with information about font
     */
    font: UnifiedFont;
    /**
     * Is element fully visible
     */
    isVisible: boolean;
    /**
     * From 0 to 1
     */
    proximity: number;
}

const { font, isVisible, proximity }: Props = $props();

let selected = $state(selectedFontsStore.has(font.id));
let timeoutId = $state<NodeJS.Timeout | null>(null);

// Create a spring for smooth scale animation
const scale = new Spring(1, {
    stiffness: 0.3,
    damping: 0.7,
});

// Springs react to the virtualizer's computed state
const bloom = new Spring(0, {
    stiffness: 0.15,
    damping: 0.6,
});

// Sync spring to proximity for a "Lens" effect
$effect(() => {
    bloom.target = isVisible ? 1 : 0;
});

$effect(() => {
    selected = selectedFontsStore.has(font.id);
});

$effect(() => {
    return () => {
        if (timeoutId) {
            clearTimeout(timeoutId);
        }
    };
});

function handleClick() {
    animateSelection();
    selected ? selectedFontsStore.removeOne(font.id) : selectedFontsStore.addOne(font);
}

function animateSelection() {
    scale.target = 0.98;

    timeoutId = setTimeout(() => {
        scale.target = 1;
    }, 150);
}
</script>

<div
    class={cn('pb-1 will-change-transform')}
    style:opacity={bloom.current}
    style:transform="
		scale({0.92 + (bloom.current * 0.08)})
		translateY({(1 - bloom.current) * 10}px)
	"
>
    <div style:transform={`scale(${scale.current})`}>
        <div
            class={cn(
                'w-full hover:bg-accent/50 flex items-start gap-3 rounded-lg border border-transparent p-3',
                'active:transition-transform active:duration-150',
                'border dark:border-slate-800',
                'bg-white/10 border-white/20',
                isVisible && 'bg-white/40 border-white/40',
                selected && 'ring-2 ring-indigo-600 ring-inset bg-indigo-50/50 hover:bg-indigo-50',
            )}
            role="button"
            tabindex="0"
            onmousedown={(e => {
                // Prevent browser focus-jump
                if (e.currentTarget === document.activeElement) return;
                e.preventDefault();
                handleClick();
            })}
            onkeydown={(e => {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    handleClick();
                }
            })}
        >
            <div class="w-full">
                <div class="flex flex-row gap-1 w-full items-center justify-between">
                    <div class="flex flex-col gap-1 transition-all duration-150 ease-out">
                        <div class="flex flex-row gap-1">
                            <Badge
                                variant="outline"
                                class="text-[0.5rem] font-mono uppercase tracking-widest text-slate-900"
                            >
                                {font.provider}
                            </Badge>
                            <Badge
                                variant="outline"
                                class="text-[0.5rem] font-mono uppercase tracking-widest text-slate-900"
                            >
                                {font.category}
                            </Badge>
                        </div>
                        <FontApplicator
                            id={font.id}
                            className="text-2xl"
                            name={font.name}
                        >
                            {font.name}
                        </FontApplicator>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
