<script lang="ts">
    import { page } from '$app/stores'
    import { goto } from '$app/navigation'
    import { getContext } from 'svelte'
    import { fly } from 'svelte/transition'
    import { quartOut } from 'svelte/easing'
    import dayjs from 'dayjs'
    import relativeTime from 'dayjs/plugin/relativeTime'
    // Components
    import Metas from '$components/Metas.svelte'
    import IconEarth from '$components/atoms/IconEarth.svelte'
    import Button from '$components/atoms/Button.svelte'
    import Image from '$components/atoms/Image.svelte'
    import DiscoverText from '$components/atoms/DiscoverText.svelte'
    import PostCard from '$components/molecules/PostCard.svelte'
    import Select from '$components/molecules/Select.svelte'
    import Shop from '$components/organisms/Shop.svelte'
    import Newsletter from '$components/organisms/Newsletter.svelte'

    export let photos: any[]
    export let lastUpdated: string
    export let totalPhotos: number
    export let filteredCountryExists: boolean

    dayjs.extend(relativeTime)

    const { countries }: any = getContext('global')

    let buttonReset: HTMLElement
    let buttonShuffle: HTMLElement

    // Filters
    const urlFiltersParams = new URLSearchParams()
    let filtered: boolean = false
    let filterCountry: any = $page.query.get('country') || defaultCountry
    let filterSort: string = $page.query.get('sort') || defaultSort
    let countryFlagId: string

    // Pages related informations
    let currentPage: number = 1
    let ended: boolean
    let currentPhotosAmount: number
    $: currentPhotosAmount = photos.length
    $: ended = currentPhotosAmount === totalPhotos


    /**
     * Define URL params
     */
    $: {
        // Define country flag from selection
        if (filterCountry !== defaultCountry) {
            countryFlagId = countries.find((country: any) => country.slug === filterCountry).flag.id
        } else {
            countryFlagId = undefined
        }

        // Update URL filtering params from filter values
        if (filtered && filterCountry && filterSort) {
            urlFiltersParams.set('country', filterCountry)
            urlFiltersParams.set('sort', filterSort)
            goto(`${$page.path}?${urlFiltersParams.toString()}`, { keepfocus:true, replaceState:true, noscroll:true })
        }
    }


    /**
     * Select change events
     */
    // Country select
    const handleCountryChange = ({ detail: value }) => {
        console.log('country change:', value)
        filtered = true
        filterCountry = value
    }

    // Sort select
    const handleSortChange = ({ detail: value }) => {
        console.log('sort change:', value)
        filtered = true
        filterSort = value
    }


    /**
     * Reset filters
     */
    const resetFiltered = () => {
        filtered = false
        filterCountry = defaultCountry
        filterSort = defaultSort
        goto($page.path, { replaceState: true, noscroll: true })
    }


    /**
     * Load photos
     */
    // Load more photos from CTA
    const loadMorePhotos = async () => {
        // Append more photos from API including options and page
        const newPhotos: any = await loadPhotos(currentPage + 1)
        console.log(newPhotos)

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

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

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

    // [function] Load photos helper
    const loadPhotos = async (page?: number) => {
        const res = fetchAPI(`
            query {
                photos: photo (
                    filter: {
                        ${filterCountry !== 'all' ? `location: { country: { slug: { _eq: "${filterCountry}" }} },` : ''}
                        status: { _eq: "published" },
                    },
                    sort: "${filterSort === 'latest' ? '-' : ''}date_created",
                    limit: ${import.meta.env.VITE_GRID_INCREMENT},
                    page: ${page},
                ) {
                    title
                    slug
                    image {
                        id
                        title
                    }
                    location {
                        slug
                        country { slug }
                    }
                }
            }
        `)
        const { data: { photos }} = await res

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

<Metas
    title="Photos"
    description=""
    image=""
/>

<main class="photos">
    <section class="photos__intro">
        <h1 class="title-huge">Houses</h1>

        <DiscoverText />

        <div class="filter">
            <span class="text-label filter__label">Filter photos</span>

            <div class="filter__bar">
                <ul>
                    <li>
                        <Select
                            name="country" id="filter_country"
                            options={[
                                {
                                    value: 'all',
                                    name: 'Worldwide',
                                    default: filterCountry === defaultCountry
                                },
                                ...countries.map(({ slug, name }) => ({
                                    value: slug,
                                    name,
                                    default: filterCountry === slug,
                                }))
                            ]}
                            on:change={handleCountryChange}
                            value={filterCountry}
                        >
                            {#if countryFlagId}
                                <Image id={countryFlagId} width={26} height={26} alt="{filterCountry} flag" class="icon" />
                            {:else}
                                <IconEarth class="icon" />
                            {/if}
                        </Select>
                    </li>
                    <li>
                        <Select
                            name="sort" id="filter_sort"
                            options={[
                                { value: 'latest', name: 'Latest photos', default: filterSort === defaultSort },
                                { value: 'oldest', name: 'Oldest photos', default: filterSort === 'oldest' },
                            ]}
                            on:change={handleSortChange}
                            value={filterSort}
                        >
                            <svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="#fff" xmlns="http://www.w3.org/2000/svg" aria-label="Sort icon">
                                <path fill-rule="evenodd" clip-rule="evenodd" d="M15.878 15.93h-4.172c-.638 0-1.153.516-1.153 1.154 0 .639.515 1.154 1.153 1.154h4.172c.638 0 1.153-.515 1.153-1.154a1.152 1.152 0 0 0-1.153-1.153Zm3.244-5.396h-7.405c-.639 0-1.154.515-1.154 1.153 0 .639.515 1.154 1.154 1.154h7.405c.639 0 1.154-.515 1.154-1.154a1.145 1.145 0 0 0-1.154-1.153Zm3.244-5.408h-10.65c-.638 0-1.153.515-1.153 1.154 0 .639.515 1.154 1.154 1.154h10.65c.638 0 1.153-.515 1.153-1.154 0-.639-.515-1.154-1.154-1.154ZM7.37 20.679V3.376c0-.145-.03-.289-.082-.433a1.189 1.189 0 0 0-.628-.618 1.197 1.197 0 0 0-.886 0 1.045 1.045 0 0 0-.36.237c-.01 0-.01 0-.021.01L.82 7.145a1.156 1.156 0 0 0 0 1.638 1.156 1.156 0 0 0 1.637 0l2.596-2.596v11.7l-2.596-2.595a1.156 1.156 0 0 0-1.637 0 1.156 1.156 0 0 0 0 1.638l4.573 4.573c.103.103.237.185.37.247.135.062.289.082.433.082h.02c.145 0 .3-.03.433-.093a1.14 1.14 0 0 0 .629-.628.987.987 0 0 0 .092-.432Z" />
                            </svg>
                        </Select>
                    </li>
                </ul>
            </div>

            <div class="filter__actions">
                {#if filtered}
                    <button class="reset button-link" bind:this={buttonReset}
                        on:click={resetFiltered}
                        transition:fly={{ y: 4, duration: 600, easing: quartOut }}
                    >
                        Reset
                    </button>
                {/if}
                <button class="shuffle" bind:this={buttonShuffle}>
                    <svg width="14" height="14" viewBox="0 0 14 14" fill="#3C0576" xmlns="http://www.w3.org/2000/svg" aria-label="Shuffle icon">
                        <path fill-rule="evenodd" clip-rule="evenodd" d="M10.8168 13.7928C10.565 13.5166 10.565 13.0688 10.8168 12.7925L11.6371 11.8927C10.0729 11.7978 8.9174 11.2494 8.00077 10.4379C7.01752 9.56747 6.3426 8.41893 5.73606 7.382L5.72202 7.358C5.10114 6.29653 4.5499 5.35411 3.79106 4.65375C3.05738 3.97661 2.10408 3.50731 0.644748 3.50731C0.288663 3.50731 0 3.19063 0 2.8C0 2.40936 0.288666 2.09269 0.644751 2.09269C2.39889 2.0927 3.64837 2.6734 4.62121 3.57126C5.53188 4.41176 6.17567 5.5133 6.76119 6.51514L6.82133 6.61801C7.44316 7.68108 8.01476 8.63254 8.81058 9.33707C9.55258 9.99396 10.5204 10.4595 11.9721 10.491L10.8168 9.22362C10.565 8.9474 10.565 8.49956 10.8168 8.22333C11.0686 7.94711 11.4768 7.94711 11.7286 8.22333L13.8112 10.5079C14.0629 10.7842 14.0629 11.232 13.8112 11.5082L11.7286 13.7928C11.4768 14.0691 11.0686 14.0691 10.8168 13.7928ZM10.8168 5.77667C10.565 5.50045 10.565 5.0526 10.8168 4.77638L11.972 3.50905C10.5204 3.54053 9.55258 4.00608 8.81058 4.66297C8.50789 4.93094 8.23764 5.23463 7.98472 5.5666C7.73665 5.18234 7.48128 4.77156 7.2176 4.37967C7.45664 4.09011 7.71575 3.81442 8.00077 3.5621C8.9174 2.75061 10.0729 2.2022 11.6371 2.10738L10.8168 1.20745C10.565 0.931231 10.565 0.483387 10.8168 0.207166C11.0686 -0.0690553 11.4768 -0.0690553 11.7286 0.207166L13.8112 2.49177C14.0629 2.768 14.0629 3.21584 13.8112 3.49206L11.7286 5.77667C11.4768 6.05289 11.0686 6.05289 10.8168 5.77667ZM0 11.2C0 11.5907 0.288666 11.9073 0.644751 11.9073C2.39889 11.9073 3.64837 11.3266 4.62121 10.4288C4.82778 10.2381 5.02061 10.034 5.20215 9.82074C5.03927 9.5548 4.88613 9.293 4.73943 9.0422L4.73621 9.0367C4.647 8.88418 4.56006 8.73561 4.47456 8.59108C4.26231 8.86556 4.03764 9.11871 3.79106 9.34629C3.05738 10.0234 2.10408 10.4927 0.644748 10.4927C0.288663 10.4927 0 10.8094 0 11.2Z" />
                    </svg>
                </button>
            </div>
        </div>
    </section>

    <section class="photos__content">
        <div class="grid container">
            {#if photos}
                <div class="photos__grid">
                    {#each photos as { image, slug, location }}
                        <div class="photo shadow-photo">
                            <a href="/{location.country.slug}/{location.slug}/{slug}">
                                <Image id={image.id} width={1200} height={800} alt={image.title} />
                                <PostCard />
                            </a>
                        </div>
                    {/each}
                </div>

                <div class="controls grid">
                    <p class="controls__date" title={dayjs(lastUpdated).format('DD/MM/YYYY, hh:mm')}>
                        Last updated: <time datetime={dayjs(lastUpdated).format('YYYY-MM-DD')}>{dayjs().to(dayjs(lastUpdated))}</time>
                    </p>

                    <Button
                        text={!ended ? 'See more photos' : "You've seen it all!"}
                        tag="button"
                        on:click={loadMorePhotos}
                        disabled={ended}
                    />

                    <div class="controls__count">
                        <span class="current">{currentPhotosAmount}</span>
                        <span>/</span>
                        <span class="total">{totalPhotos}</span>
                    </div>
                </div>
            {:else if !filteredCountryExists}
                <div class="photos__message">
                    <p>
                        <strong>{$page.query.get('country').replace(/(^|\s)\S/g, letter => letter.toUpperCase())}</strong> is not available… yet 👀
                    </p>
                </div>
            {/if}

            <div class="grid-modules">
                <div class="wrap">
                    <Shop />
                    <Newsletter theme="light" />
                </div>
            </div>
        </div>
    </section>
</main>


<script context="module" lang="ts">
    import { fetchAPI } from '$utils/api'

    // Default filters values
    const defaultCountry = String(import.meta.env.VITE_FILTERS_DEFAULT_COUNTRY)
    const defaultSort = String(import.meta.env.VITE_FILTERS_DEFAULT_SORT)


    export async function load ({ page, fetch, session, stuff }) {
        // Query parameters
        const queryCountry = page.query.get('country') || defaultCountry
        const querySort = page.query.get('sort') || defaultSort

        const res = await fetchAPI(`
            query {
                photos: photo (
                    filter: {
                        ${queryCountry !== 'all' ? `location: { country: { slug: { _eq: "${queryCountry}" }}},` : ''}
                        status: { _eq: "published" },
                    },
                    sort: "${querySort === 'latest' ? '-' : ''}date_created",
                    limit: ${import.meta.env.VITE_GRID_AMOUNT},
                    page: 1,
                ) {
                    title
                    slug
                    image {
                        id
                        title
                    }
                    location {
                        slug
                        country { slug }
                    }
                }

                total_published: photo_aggregated {
                    count { id }
                }

                country: country (
                    filter: {
                        slug: { _eq: "${queryCountry}" },
                        status: { _eq: "published" },
                    },
                ) {
                    slug
                }

                lastUpdated: photo (limit: 1, sort: "-date_created", filter: { status: { _eq: "published" }}) {
                    date_created
                }
            }
        `)

        const { data } = res

        return {
            props: {
                photos: data.photos,
                filteredCountryExists: data.country.length > 0,
                totalPhotos: data.total_published[0].count.id,
                lastUpdated: data.lastUpdated[0].date_created,
            }
        }
    }
</script>
