<template lang="pug">
.page--single.f-col.between
    article.w-max.f-grow.shadow(v-if="!singlePost || loading")
        header
            p loading...
    article(v-else).w-max.f-grow.shadow
        header
            //- breadcrumb links at top of page, needs link routing
            breadcrumb(:type="type" :post="singlePost")

            h1.t-b {{ singlePost.title }}
            .date-info.t-cntr(v-if="['exhibition', 'event'].includes(type)")
                //- for events display: date, time-time
                h4(v-if="singlePost.start, singlePost.end && type == 'event'") {{ dateFrom(singlePost.start, type == 'event') }} - {{ dateFrom(singlePost.end, type == 'event').split(',')[1] }}
                //- else for single, exhibition: date-date
                h4(v-else-if="singlePost.start, singlePost.end") {{ dateFrom(singlePost.start, type == 'event') }} - {{ dateFrom(singlePost.end, type == 'event') }}
        
        //- WP main content
        section.content(v-html="singlePost.content")

        //- related artists section for episodes
        template(v-if="type === 'episode' && post")
            section.related-artists
                h2.t-up featured in this episode
                ul
                    li.f-row.between(v-for="artist in p2pPostsByType['artist']")
                        card(:content="artist" type="artist" :wide="true" :hide-type="true")

            credits(:post="singlePost")

        //- end of article icon
        footer.f-col
            img(src="../star.svg")

        vue-easy-lightbox(
            :visible="activeGalleryIndex >= 0"
            :imgs="activeGalleryImages"
            :index="activeImageIndex"
            @hide="activeGalleryIndex = -1"
        )

    sidebar(:type="`${type}`" layout="single" :related="p2pPostsByType")
</template>

<script>
import card from '@/components/card.vue'
import sidebar from '@/components/sidebars/sidebar'
import gallery from '@/components/gallery/'
import credits from '@/components/credits'
import breadcrumb from '@/components/breadcrumb'

import { postTypeGetters, scrollTop, heroUtils } from './mixin-post-types'

import { postTypes, convertTitleCase, formatDate } from '@/utils/helpers'
import { nextTick } from '@vue/runtime-core'

export default {
    components: { sidebar, gallery, credits, card, breadcrumb },
    mixins: [postTypeGetters, scrollTop, heroUtils],
    data() {
        return {
            activeGalleryIndex: -1,
            activeImageIndex: 0,
            loading: true,
        }
    },
    computed: {
        type() {
            return postTypes.includes(this.$route.params.type)
                ? this.$route.params.type
                : 'post'
        },
        slug() {
            return this.$route.params.slug
        },
        /**
         * We get the actual post data using the slug
         * Careful with name collisions with vuex helpers
         */
        singlePost() {
            const postType = this.type == 'blog' ? 'post' : this.type
            if (!this[postType]) return

            // State not a getter!
            const singleOfTypeFromState =
                this[postType][`single${convertTitleCase(postType)}`]

            return singleOfTypeFromState ? singleOfTypeFromState : {}
        },
        singlePostGalleries() {
            if (!this.singlePost.galleries) return
            const galleries = []
            this.singlePost.galleries.forEach(gallery => {
                if (!gallery.ids) return
                const withImages = gallery.ids.map(
                    imageId => this.singlePost.attached[imageId],
                )
                galleries.push(withImages)
            })
            return galleries
        },
        activeGalleryImages() {
            if (!this.singlePostGalleries || this.activeGalleryIndex < 0)
                return []
            return this.singlePostGalleries[this.activeGalleryIndex]
        },
        p2pPostsByType() {
            return this.singlePost && this.singlePost.relatedto
                ? Object.values(this.singlePost.relatedto).reduce(
                      (byType, relatedPost) => {
                          if (!byType[relatedPost.type])
                              byType[relatedPost.type] = []
                          byType[relatedPost.type].push(relatedPost)
                          return byType
                      },
                      {},
                  )
                : {}
        },
    },
    methods: {
        // _setHeroInfo(post) {} from mixin
        // _clearHero(store) {} from mixin
        /**
         * Everytime the post object changes
         * we use this to set a new HERO
         * in vuex
         * @param {object} post
         */
        checkAndSetHero(post) {
            this._clearHero(this.$store)
            if (!post) throw `No post found. Cannot set hero.`
            this.$store.commit('SET_HERO', this._setHeroInfo(post))
        },

        /**
         * Date Object from unix strings from db
         */
        dateFrom: (unix, includeTime) => formatDate(unix, includeTime),

        async loadPostData() {
            this.loading = true
            /**
             * Conditionally load based on post type
             * which is derived from the route
             */
            // modules are NOT plural because module key
            const postType = this.type == 'blog' ? 'post' : this.type
            if (!this.$store.state[postType]) return
            const allPostsOfTypeInStore = this.$store.state[postType].all

            /**
             * Load posts if they're not already in state
             */
            // Find the single post from api if it's not already in state
            // Then add it to our list
            let singlePostData = allPostsOfTypeInStore.filter(
                post => post.slug == this.slug,
            )[0]

            // Look if it exists before you try and load everything!
            if (!singlePostData) {
                console.warn(
                    'Could not find single post in store; Fetching everything...',
                )
                const res = await this.$store.dispatch(
                    `getAll${convertTitleCase(postType)}s`,
                    { sortType: null, params: null },
                )
                singlePostData = res.filter(post => post.slug == this.slug)[0]
            }

            /**
             * At the point we MUST have singlePostData
             */
            try {
                this.checkAndSetHero(singlePostData)
                this.$store.dispatch(
                    `getSingle${convertTitleCase(postType)}`,
                    singlePostData.id,
                )
            } catch (err) {
                console.error(err)
            }
            this.loading = false
        },
        _setClick(el, cb) {
            if (el.addEventListener) {
                el.addEventListener('click', cb, false)
            } else {
                el.attachEvent('onclick', cb)
            }
        },
    },
    watch: {
        slug(newSlug, oldSlug) {
            // ONLY load post data when navigating TO a single page
            // OR when navigating TO a single page from a single page
            if ((newSlug && !oldSlug) || (newSlug && oldSlug)) {
                this._clearHero(this.$store)
                this.loadPostData()
            }
        },
        async singlePost(post) {
            if (!this.$el) return
            const section = this.$el.children[0].querySelector('section')
            await nextTick()
            const galleryBlocks = section.querySelectorAll('.wp-block-gallery')
            galleryBlocks.forEach((block, blockIndex) => {
                block.querySelectorAll('img').forEach(image => {
                    image.dataset.gallery = blockIndex
                    this._setClick(image, e => {
                        this.activeGalleryIndex = e.target.dataset.gallery
                        const activeGallery =
                            post.galleries[this.activeGalleryIndex]

                        if (!activeGallery.ids) return

                        this.activeImageIndex = activeGallery.ids.indexOf(
                            parseInt(e.target.dataset.id),
                        )
                    })
                })
            })
        },
    },
    created() {
        this.loadPostData()
    },
    beforeDestroy() {},
}
</script>

<style lang="postcss">
// prettier-ignore
@import '../sss/variables.sss'
@import '../sss/theme.sss'

.page--single
    article
        background-color: white
        padding: $ms-0
        h1
            /* color: $cia_black */
            margin: 0 0 $ms--3 0
        > ul
            /* grid-gap: $ms-0 */
            list-style: none
            /* change to a 1/3 width of the article*/
            img.feature
                width: 20em 

        /* wp-block-embed youtube link */
        .wp-block-embed, .is-type-video
            position: relative
            width: 100% 
            padding-bottom: 56.25%
            margin-bottom: $ms-7
            &__wrapper
                display: contents
            /* TBD if kept- edit ot test */
            figcaption 
                position: absolute
                top: 100%

        .wp-block-gallery
            margin: 0 0 0.5em 0
            grid-gap: $ms--5
            > .wp-block-image  
                figcaption
                    position: inherit
                    background: none
                    font-size: $ms--1
                    color: $cia_black
                    max-height: 9%
                    overflow: visible 
                    padding: 0 
                    margin-bottom: 2.5em
            figcaption
                flex-direction: column

        /* iframe container 16:9 */
        [class^="iframe-container"]
            position: relative
            padding-bottom: 56.25% 
            /* width: 100%  */
        /* iframe container portrait */
        .iframe-container-v
            height: 100%
            padding-bottom: 125%
        iframe 
            position: absolute
            top: 0 
            left: 0
            width: 100% 
            height: 100%

        /* separator styles */
        * hr
            margin: $ms-2 auto
            &.is-style
                &-default
                    width: 15vw
                &-wide
                    width: 50vw
                &-dots::before
                    outline-style: none
                    font-weight: bolder
                    letter-spacing: $ms-8
                    padding-left: $ms-8
        /* margin to indent marker */
        li
            margin: 0 0 $ms--2 $ms-4

        .related-artists
            ul li
                margin: 0 0 $ms-0 0
                .card
                    padding: 0 0 $ms--2
                    min-height: auto

        breadcrumb
            h5
                color: $cia_red
        
        //- end of article icon
        footer
            padding: $ms-6 0
            img
                height: $ms-3
                width: $ms-3

        
@media (min-width: $medium)
    .page--single
        > article
            margin: 0 0.65em 0 0
        &.f-col
            flex-direction: row
            .wp-block-gallery
                .wp-block-image  
                    figcaption
                        max-height: 5%
                        margin-bottom: $ms-4            
</style>
