<style lang="scss">
    @import "../../style/organisms/carousel";
</style>

<script lang="ts">
    import { onMount } from 'svelte'
    import { writable } from 'svelte/store'
    import EmblaCarousel, { type EmblaCarouselType } from 'embla-carousel'
    // Components
    import Image from '$components/atoms/Image.svelte'

    export let slides: any

    let arrowEl: HTMLElement
    let carouselEl: HTMLElement
    let carousel: EmblaCarouselType
    let currentSlide = 0
    let arrowDirection: string = null
    $: isFirstSlide = currentSlide === 0
    $: isLastSlide = currentSlide === slides.length - 1


    /** Navigate to specific slide */
    const goToSlide = (index: number = 0) => carousel.scrollTo(index)

    /** Move and change arrow direction when moving */
    const arrowPosition = writable({ x: 0, y: 0 })

    /** Move arrow and define direction on mousemove */
    const handleArrowMove = (event: MouseEvent) => {
        const { left, top, width } = carouselEl.getBoundingClientRect()
        const offsetX = event.clientX - left
        const offsetY = event.clientY - top

        // Define direction
        if (isFirstSlide) {
            arrowDirection = 'next'
        } else if (isLastSlide) {
            arrowDirection = 'prev'
        } else {
            arrowDirection = offsetX < Math.round(width / 2) ? 'prev' : 'next'
        }

        // Move arrow
        arrowPosition.set({
            x: offsetX - 12,
            y: offsetY - 56,
        })
    }

    /** Go to prev or next slide depending on direction */
    const handleArrowClick = () => {
        if (!carousel.clickAllowed()) return

        // Define direction
        if (isFirstSlide) {
            arrowDirection = 'next'
        } else if (isLastSlide) {
            arrowDirection = 'prev'
        }

        // Click only if carousel if being dragged
        if (arrowDirection === 'prev') {
            carousel.scrollPrev()
        } else {
            carousel.scrollNext()
        }
    }


    onMount(() => {
        // Init carousel
        carousel = EmblaCarousel(carouselEl, {
            loop: false
        })
        carousel.on('select', () => {
            currentSlide = carousel.selectedScrollSnap()
        })


        // Destroy
        return () => {
            carousel.destroy()
        }
    })
</script>

<div class="carousel {$$props.class ?? ''}">
    {#if slides.length}
        <div class="carousel__viewport" bind:this={carouselEl}
            on:mousemove={handleArrowMove}
            on:click={handleArrowClick}
        >
            <div class="carousel__slides">
                {#each slides as { id, alt }}
                    <Image
                        class="carousel__slide"
                        id={id}
                        sizeKey="product"
                        sizes={{
                            small: { width: 300 },
                            medium: { width: 550 },
                            large: { width: 800 },
                        }}
                        ratio={1.5}
                        alt={alt}
                    />
                {/each}
            </div>
        </div>

        <ul class="carousel__dots">
            {#each slides as _, index}
                <li class:is-active={index === currentSlide}>
                    <button on:click={() => goToSlide(index)} aria-label="Go to slide #{index + 1}" />
                </li>
            {/each}
        </ul>

        <span class="carousel__arrow" bind:this={arrowEl}
            style="--x: {$arrowPosition.x}px; --y: {$arrowPosition.y}px;"
            class:is-flipped={arrowDirection === 'prev' && !isFirstSlide || isLastSlide}
        >
            <svg width="29" height="32">
                <use xlink:href="#arrow" />
            </svg>
        </span>
    {/if}
</div>