<!--
    Component: PerspectivePlan
    Wrapper that applies perspective transformations based on back/front state.
    Style computation moved from manager to component for simpler architecture.
-->
<script lang="ts">
import type { PerspectiveManager } from '$shared/lib';
import clsx from 'clsx';
import { type Snippet } from 'svelte';

interface Props {
    /**
     * Perspective manager
     */
    manager: PerspectiveManager;
    /**
     * CSS classes
     */
    class?: string;
    /**
     * Content snippet
     */
    children: Snippet<[{ className?: string }]>;
    /**
     * Constrain region
     * @default 'full'
     */
    region?: 'left' | 'right' | 'full';
    /**
     * Region width percentage
     * @default 50
     */
    regionWidth?: number;
}

let { manager, children, class: className = '', region = 'full', regionWidth = 50 }: Props = $props();

const config = $derived(manager.getConfig());

// Computed style based on spring position (0 = front, 1 = back)
const style = $derived.by(() => {
    const distance = manager.spring.current;
    const baseX = config.horizontalOffset ?? 0;

    // Back state: blurred, scaled down, pushed back
    // Front state: fully visible, in focus
    const scale = 1 - distance * (config.scaleStep ?? 0.5);
    const blur = distance * (config.blurStep ?? 4);
    const opacity = Math.max(0, 1 - distance * (config.opacityStep ?? 0.5));
    const zIndex = 10;
    const pointerEvents = distance < 0.4 ? 'auto' : ('none' as const);

    return {
        transform: `translate3d(${baseX}px, 0px, ${-distance * (config.depthStep ?? 100)}px) scale(${scale})`,
        filter: `blur(${blur}px)`,
        opacity,
        pointerEvents,
        zIndex,
    };
});

// Calculate horizontal constraints based on region
const regionStyleStr = $derived(() => {
    if (region === 'full') {
        return '';
    }
    const side = region === 'left' ? 'left' : 'right';
    return `position: absolute; ${side}: 0; width: ${regionWidth}%; top: 0; bottom: 0;`;
});

// Visibility: front = visible, back = hidden
const isVisible = $derived(manager.isFront);
</script>

<div
    class={clsx('will-change-transform', className)}
    style:transform-style="preserve-3d"
    style:transform={style?.transform}
    style:filter={style?.filter}
    style:opacity={style?.opacity}
    style:pointer-events={style?.pointerEvents}
    style:z-index={style?.zIndex}
    style:custom={regionStyleStr()}
>
    {@render children({ className: isVisible ? 'visible' : 'hidden' })}
</div>
