<template lang="pug">
.page--single.f-col.between
    gallery(v-if="activeGalleryIndex >= 0" :activeImageIndex="activeImageIndex" :images="imagesInGallery" @close="closeGallery")

    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 }}
            //- p(v-if="singlePost.categories") categories: {{ singlePost.categories }}
            //- p(v-if="singlePost.type") type: {{ singlePost.type }}
            //- p(v-if="singlePost.subtypes") subtypes: {{ singlePost.subtypes }}

            .date-info(v-if="['exhibition', 'event'].includes(type)")
                p start: {{ dateFrom(singlePost.start, type == 'event') }}
                p end: {{ dateFrom(singlePost.end, type == 'event') }}

        //- WP main content
        section.content(v-html="singlePost.content")

        //- related artists section for episodes
        section(v-if="type === 'episode' && post").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(v-if="type === 'episode' && singlePost" :post="singlePost")

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

    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'

const TIMEOUT = 1

export default {
    components: { sidebar, gallery, credits, card, breadcrumb },
    mixins: [postTypeGetters, scrollTop, heroUtils],
    data() {
        return {
            // Gallery control
            activeGalleryIndex: -1,
            activeImageID: -1,
            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() {
            if (!this[this.type]) return

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

            if (!singleOfTypeFromState) return

            return singleOfTypeFromState
        },

        idsForGallery() {
            if (!this.singlePost || this.activeGalleryIndex < 0) return []
            return this.singlePost.galleries[this.activeGalleryIndex].ids
        },
        /**
         * We need a convenient way to get all the images
         * broken down by gallery. We use the active gallery
         * image IDs to create a map. We match the ID to the
         * image size and url information returned by singlePost.attached
         */
        imagesInGallery() {
            if (!this.activeGalleryIndex < 0) return {}

            return this.idsForGallery.reduce((imageMap, id) => {
                imageMap[id] = this.singlePost.attached[parseInt(id)]
                return imageMap
            }, {})
        },
        activeImageIndex() {
            return Object.keys(this.imagesInGallery).indexOf(
                this.activeImageID.toString(),
            )
        },
        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: {
        /**
         * We set the active gallery to the index.
         * Everything kicks off when activeGallery
         * is set. We also need to set the activeImageID
         * to the image clicked
         * @param {string} imageInfo
         */
        openGallery(imageInfo) {
            const byIndex = this.singlePost.galleries.reduce(
                (byIndex, gallery, index) => {
                    byIndex[index] = gallery.ids
                    return byIndex
                },
                {},
            )
            let matchingIndex = 0
            Object.keys(byIndex).forEach(galleryIndex => {
                if (
                    byIndex[galleryIndex].includes(
                        parseInt(imageInfo.dataset.id)
                    )
                )
                    matchingIndex = galleryIndex
            })
            this.activeGalleryIndex = matchingIndex
            this.activeImageID = imageInfo.dataset.id
                ? parseInt(imageInfo.dataset.id)
                : parseInt(imageInfo.className.split('-').pop())
        },
        closeGallery() {
            this.activeGalleryIndex = this.activeImageID = -1
        },
        // _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
            if (!this.$store.state[this.type]) return
            const allPostsOfTypeInStore = this.$store.state[this.type].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(this.type)}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)
                await this.$store.dispatch(
                    `getSingle${convertTitleCase(this.type)}`,
                    singlePostData.id,
                )
            } catch (err) {
                console.error(err)
            }
            this.loading = false
        },
    },
    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()
            }
        },
    },
    created() {
       this.loadPostData()
    },
}
</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 
            li
        /* 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%

        [class^="iframe-container"]
            position: relative
            width: 100% 
        /* iframe container 16:9 */
        .iframe-container 
            padding-bottom: 56.25% 

        /* iframe container portrait */
        .iframe-container-v
            height: 100%
            padding-bottom: 125%
            
        iframe 
            position: absolute 
            top: 0px 
            left: 0px 
            width: 100% 
            height: 100%
        /* separator styles */
        * hr
            margin: $ms-2 auto
            &.is-style
                &-default
                    height: 1px
                    width: 15vw
                &-wide
                    height: 3px
                    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: yellow */
                color: $cia_red
                /* font-weight: 400 */
                /* padding: $ms--6 0 */
        
        //- 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
</style>
