<style lang="scss">
    @import "../../../style/pages/location";
</style>

<script lang="ts">
    import { page, navigating } from '$app/stores'
    import type { PageData } from './$types'
    import { onMount } from 'svelte'
    import { stagger, timeline } from 'motion'
    import dayjs from 'dayjs'
    import relativeTime from 'dayjs/plugin/relativeTime'
    import { quartOut } from '$animations/easings'
    import { getAssetUrlKey } from '$utils/api'
    import { DELAY } from '$utils/contants'
    import { photoFields } from './+page.server'
    import { PUBLIC_LIST_INCREMENT } from '$env/static/public'
    // Components
    import Metas from '$components/Metas.svelte'
    import PageTransition from '$components/PageTransition.svelte'
    import Image from '$components/atoms/Image.svelte'
    import Button from '$components/atoms/Button.svelte'
    import IconEarth from '$components/atoms/IconEarth.svelte'
    import House from '$components/molecules/House.svelte'
    import Pagination from '$components/molecules/Pagination.svelte'
    import NewsletterModule from '$components/organisms/NewsletterModule.svelte'
    import ShopModule from '$components/organisms/ShopModule.svelte'

    export let data: PageData

    let { photos, totalPhotos }: { photos: any[], totalPhotos: number } = data
    $: ({ photos, totalPhotos } = data)
    const { location, product = undefined }: { location: any, totalPhotos: number, product: any } = data
    const { params } = $page

    dayjs.extend(relativeTime)

    let introEl: HTMLElement
    let photosListEl: HTMLElement
    let scrollY: number
    let observerPhotos: IntersectionObserver
    let mutationPhotos: MutationObserver
    let currentPage = 1
    let ended: boolean
    let currentPhotosAmount: number
    let illustrationOffsetY = 0

    $: latestPhoto = photos[0]
    $: currentPhotosAmount = photos.length
    $: ended = currentPhotosAmount === totalPhotos
    $: hasIllustration = location.illustration_desktop && location.illustration_desktop_2x && location.illustration_mobile


    /**
     * Load photos
     */
    // Load more photos from CTA
    const loadMorePhotos = async () => {
        // Append more photos from API
        const newPhotos: any = await loadPhotos(currentPage + 1)

        if (newPhotos) {
            photos = [...photos, ...newPhotos]

            // Define actions if the number of new photos is the expected ones
            if (newPhotos.length === Number(PUBLIC_LIST_INCREMENT)) {
                // Increment the current page
                currentPage++
            }

            // Increment the currently visible amount of photos
            currentPhotosAmount += newPhotos.length
        }
    }

    // Load photos helper
    const loadPhotos = async (page?: number) => {
        const res = await fetch('/api/data', {
            method: 'POST',
            body: `query {
                photos: photo (
                    filter: {
                        location: { slug: { _eq: "${params.location}" }},
                        status: { _eq: "published" },
                    },
                    sort: "-date_created",
                    limit: ${PUBLIC_LIST_INCREMENT},
                    page: ${page},
                ) {
                    ${photoFields}
                }
            }`,
        })
        const { data: { photos }} = await res.json()

        if (photos) {
            // Return new photos
            return photos
        } else {
            throw new Error('Error while loading new photos')
        }
    }


    /**
     * Add parallax on illustration when scrolling
     */
    $: if (scrollY && scrollY < introEl.offsetHeight) {
        illustrationOffsetY = scrollY * 0.1
    }


    onMount(() => {
        // Photos IntersectionObserver
        observerPhotos = new IntersectionObserver(entries => {
            entries.forEach(({ isIntersecting, target }: IntersectionObserverEntry) => {
                target.classList.toggle('is-visible', isIntersecting)

                // Run effect once
                isIntersecting && observerPhotos.unobserve(target)
            })
        }, {
            threshold: 0.3,
            rootMargin: '0px 0px 0px'
        })

        // Photos MutationObserver
        if (photos.length) {
            mutationPhotos = new MutationObserver((mutationsList) => {
                // When adding new childs
                for (const mutation of mutationsList) {
                    if (mutation.type === 'childList') {
                        // Observe new items
                        Array.from(mutation.addedNodes)
                            .filter(item => item.nodeType === Node.ELEMENT_NODE)
                            .forEach((item: HTMLElement) => observerPhotos.observe(item))
                    }
                }
            })
            mutationPhotos.observe(photosListEl, {
                childList: true,
            })

            // Observe existing elements
            const existingPhotos = photosListEl.querySelectorAll('.house')
            existingPhotos.forEach(el => observerPhotos.observe(el))
        }


        /**
         * Animations
         */
        const animation = timeline([
            // Title word
            ['.location-page__intro .word', {
                y: ['110%', 0],
            }, {
                at: 0.2,
                delay: stagger(0.4)
            }],

            // Illustration
            ['.location-page__illustration', {
                scale: [1.06, 1],
                opacity: [0, 1],
            }, {
                at: 0.4,
                duration: 2.4,
            }],

            // Title of
            ['.location-page__intro .of', {
                opacity: [0, 1],
            }, {
                at: 0.95,
                duration: 1.2,
            }],

            // Description
            ['.location-page__description', {
                y: ['10%', 0],
                opacity: [0, 1],
            }, {
                at: 0.9,
                duration: 1.2,
            }]
        ], {
            delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0,
            defaultOptions: {
                duration: 1.6,
                easing: quartOut,
            },
        })
        animation.stop()

        // Run animation
        requestAnimationFrame(animation.play)


        // Destroy
        return () => {
            observerPhotos && observerPhotos.disconnect()
            mutationPhotos && mutationPhotos.disconnect()
        }
    })
</script>

<Metas
    title="Houses Of {location.name}"
    description="Discover {totalPhotos} beautiful homes from {location.name}, {location.country.name}"
    image={latestPhoto ? getAssetUrlKey(latestPhoto.image.id, 'share-image') : null}
/>

<svelte:window bind:scrollY />


<PageTransition name="location-page">
    <section class="location-page__intro grid" bind:this={introEl}>
        <h1 class="title" class:is-short={location.name.length <= 4}>
            <span class="housesof mask">
                <strong class="word">Houses</strong>
                <span class="of">of</span>
            </span>
            <strong class="city mask">
                <span class="word">{location.name}</span>
            </strong>
        </h1>

        <div class="location-page__description grid">
            <div class="wrap">
                <div class="text-medium">
                    Houses of {location.name} {location.description ?? 'has no description yet'}
                </div>
                <div class="info">
                    <p class="text-label">
                        Photos by
                        {#each location.credits as { credit_id: { name, website }}}
                            {#if website}
                                <a href={website} target="_blank" rel="noopener external">
                                    {name}
                                </a>
                            {:else}
                                <span>{name}</span>
                            {/if}
                        {/each}
                    </p>
                    {#if latestPhoto}
                        &middot;
                        <p class="text-label" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
                            Updated <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>
                                {dayjs().to(dayjs(latestPhoto.date_created))}
                            </time>
                        </p>
                    {/if}
                </div>

                <div class="ctas">
                    <Button url="/locations" text="Change location" class="shadow-small">
                        <IconEarth />
                    </Button>

                    {#if location.has_poster}
                        <Button url="/shop/poster-{location.slug}" text="Buy the poster" color="pinklight" class="shadow-small">
                            <!-- <IconEarth /> -->
                        </Button>
                    {/if}
                </div>
            </div>
        </div>

        {#if hasIllustration}
            <picture class="location-page__illustration" style:--parallax-y="{illustrationOffsetY}px">
                <source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.illustration_desktop_2x.id, 'illustration-desktop-2x')}>
                <source media="(min-width: 768px)" srcset={getAssetUrlKey(location.illustration_desktop.id, 'illustration-desktop-1x')}>
                <img
                    src={getAssetUrlKey(location.illustration_mobile.id, 'illustration-mobile')}
                    width={320}
                    height={824}
                    alt="Illustration for {location.name}"
                    decoding="async"
                />
            </picture>
        {/if}
    </section>

    {#if photos.length}
        <section class="location-page__houses" bind:this={photosListEl} data-sveltekit-noscroll>
            {#each photos as { title, image: { id, title: alt, width, height }, slug, city, date_taken }, index}
                <House
                    {title}
                    photoId={id}
                    photoAlt={alt}
                    url="/{params.country}/{params.location}/{slug}"
                    {city}
                    location={location.name}
                    ratio={width / height}
                    date={date_taken}
                    index={(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}
                />
            {/each}
        </section>

        <section class="location-page__next container">
            <Pagination
                ended={ended}
                current={currentPhotosAmount}
                total={totalPhotos}
                on:click={!ended && loadMorePhotos}
            >
                {#if !ended}
                    <p class="more">See more photos</p>
                {:else}
                    <p>You've seen it all!</p>
                {/if}
            </Pagination>

            {#if ended}
                <div class="grid-modules">
                    <div class="container grid">
                        <div class="wrap">
                            {#if location.has_poster}
                                <ShopModule
                                    title="Poster available"
                                    text="Houses of {location.name} is available as a poster on our shop."
                                    images={product.photos_product}
                                    textBottom={null}
                                    buttonText="Buy"
                                    url="/shop/poster-{location.slug}"
                                />
                            {:else}
                                <ShopModule />
                            {/if}
                            <NewsletterModule theme="light" />
                        </div>
                    </div>
                </div>
            {/if}

            {#if location.acknowledgement}
                <div class="acknowledgement">
                    <Image
                        class="flag"
                        id={location.country.flag.id}
                        sizeKey="square-small"
                        width={32} height={32}
                        alt="Flag of {location.country.name}"
                    />
                    <p>{location.acknowledgement}</p>
                </div>
            {/if}
        </section>
    {:else}
        <div class="location-page__message">
            <p>
                No photos available for {location.name}.<br>
                Come back later!
            </p>
        </div>
    {/if}
</PageTransition>