<script>
    import { onMount, createEventDispatcher } from 'svelte'
    import { stores } from '@sapper/app'
    import { currentLocation, fullscreen } from 'utils/store'
    import { getThumbnail, formatDate } from 'utils/functions'
    const dispatch = createEventDispatcher()
    const { page } = stores()

    // Dependencies
    import SwipeListener from 'swipe-listener'
    import lazySizes from 'lazysizes'

    // Animations
    import { animateIn } from 'animations/Carousel'

    // Components
    import IconArrow from 'atoms/IconArrow'
    import Counter from 'atoms/Counter'
    import PaginationDots from 'molecules/PaginationDots'

    // Props and Variables
    export let photos
    export let viewer = false
    export let locationUrl = false
    let scope
    let swiped
    let currentIndex = 0

    // Reactive variables from currentIndex
    $: currentPhoto = photos[currentIndex] || null
    $: prevPhoto = photos[currentIndex - 1] || photos[photos.length - 1]
    $: nextPhoto = photos[currentIndex + 1] || photos[0]

    // Default size for the image
    const defaultWidth = 900
    const defaultHeight = Math.ceil(defaultWidth / 1.5)


    /*
    ** Navigate to a photo
    */
    // Change current index from param
    const goToPhoto = to => {
        if (to === 'prev') {
            currentIndex--
            currentIndex = (currentIndex < 0) ? photos.length - 1 : currentIndex
        } else if (to === 'next') {
            currentIndex++
            currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
        } else {
            currentIndex = to
        }

        // Dispatch current photo
        dispatch('photoChange', photos[currentIndex])
        // Reset fullscreen value if open
        if ($fullscreen) fullscreen.set()
        // Reset swiped event if fired
        swiped = false
    }

    // Hover on controls
    const hoverPhoto = event => {
        const button = event.currentTarget.querySelector('button')
        const photoActive = scope.querySelector('.is-active')

        let photoToHover
        if (event.currentTarget.dataset.to === 'prev') {
            photoToHover = (photoActive.previousSibling != null) ? photoActive.previousSibling : photoActive.parentNode.lastChild
        } else {
            photoToHover = (photoActive.nextSibling != null) ? photoActive.nextSibling : photoActive.parentNode.firstChild
        }

        // Toggle class and focus of the button
        if (event.type === 'mouseenter') {
            photoToHover.classList.add('hover')
            button.classList.add('hover')
        } else if (event.type === 'mouseleave') {
            photoToHover.classList.remove('hover')
            button.classList.remove('hover')
        }
    }

    // Open fullscreen
    const openFullscreen = event => {
        if (!swiped) {
            fullscreen.set(currentPhoto)
        }
        // Reset swiped event if fired
        swiped = false
    }


    /*
    ** Navigation
    */
    // Drag and swipe
    const swipe = directions => {
        swiped = true

        // Detect swipe direction
        if (directions.right) {
            goToPhoto('prev')
        } else if (directions.left) {
            goToPhoto('next')
        }
    }

    // Keyboard navigation
    const keyboardNav = event => {
        if ([37,80,74].includes(event.keyCode)) {
            goToPhoto('prev')
        } else if ([39,78,75].includes(event.keyCode)) {
            goToPhoto('next')
        }
    }


    /*
    ** Run code when mounted
    */
    onMount(() => {
        // Entering transition
        animateIn(scope)

        // Enable gestures
        const touch = SwipeListener(scope)

        // Viewer: Navigate to photo on init and URL change
        if (viewer) {
            page.subscribe(page => {
                if (page.path.includes('/viewer/')) {
                    goToPhoto(photos.findIndex(photo => photo.slug === page.params.photo))
                }
            })
        }
    })
</script>

<svelte:window on:keydown={keyboardNav} />

<div class="carousel" role="region" aria-label="Photos"
    bind:this={scope}
    on:swipe={event => swipe(event.detail.directions)}
>
    <div class="wrap">
        <div class="gallery">
            <div class="gallery__images">
                {#each photos as { id, name, location, image }, index}
                <div class="gallery__photo"
                    class:is-prev={id === prevPhoto.id}
                    class:is-active={id === currentPhoto.id}
                    class:is-next={id === nextPhoto.id}
                    role="tabpanel"
                    aria-label="Photo {index + 1} of {photos.length}"
                    aria-hidden={index === currentIndex ? undefined : true}
                >
                    <picture class="gallery__picture"
                        on:click={openFullscreen}
                    >
                        <source media="(min-width: 968px)" data-srcset={getThumbnail(image.private_hash, 1200)}>
                        <source media="(min-width: 800px)" data-srcset={getThumbnail(image.private_hash, 900)}>
                        <source media="(min-width: 500px)" data-srcset={getThumbnail(image.private_hash, 600)}>
                        <source media="(min-width: 300px)" data-srcset={getThumbnail(image.private_hash, 400)}>
                        <img src={getThumbnail(image.private_hash, 900)}
                            alt="{name}, {location.name}, {location.country.name}"
                            width={defaultWidth} height={defaultHeight}
                            class:lazyload={
                                // Load the current index and the two previous/next ones
                                index === currentIndex || index >= currentIndex - 2 && index <= currentIndex + 2
                                // If last photo, load the two first ones (index = 0)
                                || currentIndex === photos.length - 1 && (index === 0 || index === 1)
                                // If first photo, load the two last ones (index = photos length)
                                || currentIndex === 0 && (index === photos.length - 1 || index === photos.length - 2)
                            }
                        >
                    </picture>
                </div>
                {/each}
            </div>

            <div class="carousel__controls">
                <div class="carousel__area carousel__area--prev" data-to="prev" rel="prev"
                    on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
                    on:click={() => goToPhoto('prev')}
                >
                    <button class="button-control button-control--white dir-left" aria-label="Previous">
                        <IconArrow direction="left" color="#ff6c89" class="icon" />
                        <IconArrow direction="left" color="#fff" class="icon" hidden="true" />
                    </button>
                </div>

                <div class="carousel__area carousel__area--next" data-to="next" rel="next"
                    on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
                    on:click={() => goToPhoto('next')}
                >
                    <button class="button-control button-control--white dir-right" aria-label="Next">
                        <IconArrow direction="right" color="#ff6c89" class="icon" />
                        <IconArrow direction="right" color="#fff" class="icon" hidden="true" />
                    </button>
                </div>
            </div>

            {#if viewer}
            <Counter {currentIndex} className="carousel__number" />
            {/if}
        </div>

        <div class="carousel__infos">
            <div class="carousel__locations">
                {#each photos as { id, name, location }, index}
                <div class="carousel__location style-location"
                    class:is-prev={id === prevPhoto.id}
                    class:is-active={id === currentPhoto.id}
                    class:is-next={id === nextPhoto.id}
                >
                    <p class="street">{name}</p>
                    <p class="state style-caps style-caps--transparent">
                        {#if locationUrl}
                        <a href="/location/{location.country.slug}/{location.slug}" sapper-noscroll>
                            {location.name}, {location.country.name}
                        </a>
                        {:else}
                            {location.name}, {location.country.name}
                        {/if}
                    </p>
                </div>
                {/each}
            </div>
            {#if viewer}
            <p class="carousel__date">{formatDate(currentPhoto.date, 'FULL')}</p>
            {/if}
        </div>
    </div>

    <PaginationDots className="carousel__dots" {photos} {currentIndex}
        on:goToIndex={event => currentIndex = event.detail}
    />
</div>
