<script lang="ts">
    import WeatherCard from "./WeatherCard.svelte";
    import type { WeatherPeriod } from "$lib/types/weather.js";
    import { onMount } from "svelte";

    interface Props {
        periods: WeatherPeriod[];
    }

    let { periods }: Props = $props();

    let cardStack = $state([...periods]);
    let currentCardIndex = $state(0);
    let isDragging = false;
    let startX = 0;
    let startY = 0;
    let currentX = 0;
    let currentY = 0;
    let topCardRef: HTMLDivElement | undefined = $state();

    const SWIPE_THRESHOLD = 100;
    const ROTATION_FACTOR = 0.1;
    const MAX_ROTATION = 15;

    function handleTouchStart(e: TouchEvent) {
        if (!topCardRef) return;

        startX = e.touches[0].clientX;
        startY = e.touches[0].clientY;
        isDragging = true;
        
        // Enable hardware acceleration and disable transitions smoothly
        topCardRef.style.willChange = "transform, opacity";
        topCardRef.style.transition = "none";
    }

    function handleTouchMove(e: TouchEvent) {
        if (!isDragging || !topCardRef) return;

        currentX = e.touches[0].clientX;
        currentY = e.touches[0].clientY;

        const deltaX = currentX - startX;
        const deltaY = currentY - startY;
        const rotation = Math.min(
            Math.max(deltaX * ROTATION_FACTOR, -MAX_ROTATION),
            MAX_ROTATION,
        );

        // Use translate3d for hardware acceleration
        topCardRef.style.transform = `translate3d(${deltaX}px, ${deltaY}px, 0) rotate(${rotation}deg)`;
        topCardRef.style.opacity = `${1 - Math.abs(deltaX) / 300}`;
    }

    function handleTouchEnd() {
        if (!isDragging || !topCardRef) return;

        isDragging = false;
        const deltaX = currentX - startX;

        if (Math.abs(deltaX) > SWIPE_THRESHOLD) {
            // Card swiped away - animate it off screen
            const direction = deltaX > 0 ? 1 : -1;
            topCardRef.style.transition =
                "transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)";
            topCardRef.style.transform = `translate3d(${direction * window.innerWidth}px, ${currentY - startY}px, 0) rotate(${direction * MAX_ROTATION * 2}deg)`;
            topCardRef.style.opacity = "0";

            // Remove the card after animation
            setTimeout(() => {
                removeTopCard();
            }, 400);
        } else {
            // Snap back to center with smooth spring-like animation
            topCardRef.style.transition =
                "transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease-out";
            topCardRef.style.transform = "translate3d(0px, 0px, 0) rotate(0deg)";
            topCardRef.style.opacity = "1";
            
            // Clean up will-change after animation
            setTimeout(() => {
                if (topCardRef) {
                    topCardRef.style.willChange = "auto";
                }
            }, 500);
        }
    }

    function removeTopCard() {
        if (cardStack.length === 0) return;

        // Remove the top card and add it to the bottom of the stack
        const removedCard = cardStack[currentCardIndex];
        cardStack = [
            ...cardStack.slice(0, currentCardIndex),
            ...cardStack.slice(currentCardIndex + 1),
            removedCard,
        ];

        // Reset the top card reference
        if (topCardRef) {
            topCardRef.style.willChange = "auto";
            topCardRef.style.transition = "none";
            topCardRef.style.transform = "translate3d(0px, 0px, 0) rotate(0deg)";
            topCardRef.style.opacity = "1";
        }
    }

    function jumpToNow() {
        if (isDragging) return; // Don't jump while dragging
        
        const now = new Date();
        const currentHour = now.getHours();
        
        // Find the period that represents the current time or closest future time
        const nowIndex = periods.findIndex(period => {
            const periodStart = new Date(period.startTime);
            return periodStart.getHours() >= currentHour;
        });
        
        if (nowIndex !== -1) {
            // Reorder the card stack to put the "now" period at the front
            const beforeNow = periods.slice(0, nowIndex);
            const fromNow = periods.slice(nowIndex);
            cardStack = [...fromNow, ...beforeNow];
            currentCardIndex = 0;
            
            // Wait a frame to ensure DOM updates, then reset the top card
            setTimeout(() => {
                if (topCardRef) {
                    topCardRef.style.willChange = "auto";
                    topCardRef.style.transition = "none";
                    topCardRef.style.transform = "translate3d(0px, 0px, 0) rotate(0deg)";
                    topCardRef.style.opacity = "1";
                }
            }, 0);
        }
    }

    // Handle mouse events for desktop testing
    function handleMouseDown(e: MouseEvent) {
        if (!topCardRef) return;

        startX = e.clientX;
        startY = e.clientY;
        isDragging = true;
        
        // Enable hardware acceleration and disable transitions smoothly
        topCardRef.style.willChange = "transform, opacity";
        topCardRef.style.transition = "none";
        e.preventDefault();
    }

    function handleMouseMove(e: MouseEvent) {
        if (!isDragging || !topCardRef) return;

        currentX = e.clientX;
        currentY = e.clientY;

        const deltaX = currentX - startX;
        const deltaY = currentY - startY;
        const rotation = Math.min(
            Math.max(deltaX * ROTATION_FACTOR, -MAX_ROTATION),
            MAX_ROTATION,
        );

        // Use translate3d for hardware acceleration
        topCardRef.style.transform = `translate3d(${deltaX}px, ${deltaY}px, 0) rotate(${rotation}deg)`;
        topCardRef.style.opacity = `${1 - Math.abs(deltaX) / 300}`;
    }

    function handleMouseUp() {
        if (!isDragging || !topCardRef) return;

        isDragging = false;
        const deltaX = currentX - startX;

        if (Math.abs(deltaX) > SWIPE_THRESHOLD) {
            // Card swiped away
            const direction = deltaX > 0 ? 1 : -1;
            topCardRef.style.transition =
                "transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)";
            topCardRef.style.transform = `translate3d(${direction * window.innerWidth}px, ${currentY - startY}px, 0) rotate(${direction * MAX_ROTATION * 2}deg)`;
            topCardRef.style.opacity = "0";

            setTimeout(() => {
                removeTopCard();
            }, 400);
        } else {
            // Snap back with smooth spring-like animation
            topCardRef.style.transition =
                "transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease-out";
            topCardRef.style.transform = "translate3d(0px, 0px, 0) rotate(0deg)";
            topCardRef.style.opacity = "1";
            
            // Clean up will-change after animation
            setTimeout(() => {
                if (topCardRef) {
                    topCardRef.style.willChange = "auto";
                }
            }, 500);
        }
    }

    onMount(() => {
        document.addEventListener("mousemove", handleMouseMove);
        document.addEventListener("mouseup", handleMouseUp);

        return () => {
            document.removeEventListener("mousemove", handleMouseMove);
            document.removeEventListener("mouseup", handleMouseUp);
        };
    });
</script>

<!-- Desktop view - keep original grid layout -->
<div class="hidden md:grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
    {#each periods as period (period.number)}
        <WeatherCard {period} />
    {/each}
</div>

<!-- Mobile view - card stack -->
<div class="md:hidden">
    <div class="relative h-[360px] flex items-center justify-center">
        {#each cardStack.slice(0, 3) as period, index (period.number)}
            <div
                class="absolute w-full max-w-sm"
                style="
					z-index: {3 - index};
					transform: translate3d({index * (index % 2 === 0 ? 6 : -6)}px, {index * 8}px, 0) rotate({index * (index % 2 === 0 ? 2 : -2)}deg) scale({1 - index * 0.03});
				will-change: {index === 0 ? 'transform, opacity' : 'auto'};
					opacity: {1 - index * 0.15};
				"
            >
                {#if index === 0}
                    <div
                        bind:this={topCardRef}
                        class="cursor-grab active:cursor-grabbing"
                        ontouchstart={handleTouchStart}
                        ontouchmove={handleTouchMove}
                        ontouchend={handleTouchEnd}
                        onmousedown={handleMouseDown}
                        role="button"
                        aria-label="Swipe to dismiss card"
                        tabindex="0"
                    >
                        <WeatherCard {period} />
                    </div>
                {:else}
                    <WeatherCard {period} />
                {/if}
            </div>
        {/each}
    </div>

    <!-- Jump to now button -->
    <div class="text-center mt-4">
        <button 
            class="text-sm text-blue-500 hover:text-blue-700 underline cursor-pointer"
            onclick={jumpToNow}
        >
            jump to now
        </button>
    </div>

    <!-- Instructions -->
    <div class="text-center mt-2 text-xs text-muted-foreground">
        Swipe left or right to dismiss
    </div>
</div>
