<!--
    Component: Character
    Renders a single character with morphing animation
-->
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { comparisonStore } from '../../model';

interface Props {
    /**
     * Character
     */
    char: string;
    /**
     * Proximity value
     */
    proximity: number;
    /**
     * Past state
     */
    isPast: boolean;
}

let { char, proximity, isPast }: Props = $props();

const fontA = $derived(comparisonStore.fontA);
const fontB = $derived(comparisonStore.fontB);
const typography = $derived(comparisonStore.typography);

let slot = $state<0 | 1>(0);
let slotFonts = $state<[string, string]>(['', '']);

const displayChar = $derived(char === ' ' ? '\u00A0' : char);
const targetFont = $derived(isPast ? fontA?.name ?? '' : fontB?.name ?? '');

$effect(() => {
    if (!targetFont || slotFonts[slot] === targetFont) return;
    const next = slot === 0 ? 1 : 0;
    slotFonts[next] = targetFont;
    slot = next;
});
</script>

{#if fontA && fontB}
    <span
        class="char-wrap"
        style:font-size="{typography.renderedSize}px"
        style:will-change={proximity > 0 ? 'transform' : 'auto'}
    >
        {#each [0, 1] as s (s)}
            <span
                class={cn(
                    'char-inner',
                    isPast
                        ? 'text-swiss-black/75 dark:text-brand/75'
                        : 'text-neutral-950 dark:text-white',
                )}
                style:font-family={slotFonts[s]}
                style:font-weight={typography.weight}
                style:opacity={slot === s ? '1' : '0'}
                style:position={slot === s ? 'relative' : 'absolute'}
                aria-hidden={slot !== s ? true : undefined}
            >
                {displayChar}
            </span>
        {/each}
    </span>
{/if}

<style>
.char-wrap {
    display: inline-block;
    position: relative;
    line-height: 1;
}

.char-inner {
    top: 0;
    left: 0;
    backface-visibility: hidden;
    -webkit-font-smoothing: antialiased;
    font-synthesis: none;
    text-rendering: geometricPrecision;
    font-optical-sizing: auto;
    transition:
        opacity 0.1s ease-out,
        color 0.2s ease-out,
        transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
</style>
