<script setup>
import { onMounted, watch, ref } from 'vue';
import fm from 'front-matter';

import PostCard from '../components/PostCard.vue';


// Automatically maintained is a blog_list.json in assets/. This file contains a list of all blog posts and their metadata.
// This file is generated by a script in the root directory of the project.
import blog_list from '../assets/blog_list.json';

const modules = import.meta.glob('/blog/');

for (const path in modules) {
    const module = await modules[path]();
    console.log(path, module.default); // module.default contains the image data
}

let route = useRoute();
console.log(route)

const url = ref(null)
url.value = route.query.post
console.log(url.value)

const loading = ref(false)
const data = ref([])
const text = ref([])
const error = ref([])

const list = ref([])
const tagList = ref([])
const tagFilter = ref([])
tagFilter.value = []


const background = ref('');
const title = ref(null);
const description = ref(null);
const date = ref(null);
const tags = ref(null);
const previous = ref(null);
const next = ref(null);

// watch the params of the route to fetch the data again

watch(route, async () => {
    url.value = route.query.post
    await fetchData(route.query.post)
}, {
    immediate: true
});


async function fetchData(url) {
    error.value = data.value = null
    loading.value = true
    console.log(url)

    try {
        data.value = await $fetch(url)
        const processed = fm(data.value)
        text.value = processed.body
        background.value = processed.attributes.background
        title.value = processed.attributes.title
        description.value = processed.attributes.description
        date.value = processed.attributes.date.toLocaleDateString()
        tags.value = processed.attributes.tags

        if (processed.attributes.previous)
            previous.value = "/blog/?post=/blog/" + processed.attributes.previous
        else
            previous.value = null
        if (processed.attributes.next)
            next.value = "/blog/?post=/blog/" + processed.attributes.next
        else 
            next.value = null
    } catch (err) {
        error.value = err.toString()
        console.error(err)
        loading.value = false
    } finally {
        loading.value = false
    }
}

/* If tags are specified, include only posts with those tags */
/* else, include all posts */
async function fetchList() {
    /*Example formatting:
    {
        "posts": [
            {
                "metadata": {
                    "test": "mrrp"
                },
                "id": "test",
                "url": "/blog/test"
                },
            {
                "metadata": {
                "   title": "Awesome",    "description": "A curated list of awesome stuff I like",    "date": "2024-11-26",    "tags": ["awesome", "curated"]
                },
                "id": "awesome",
                "url": "/blog/awesome"
            },
            {
                "metadata": {
                    "test": "mrrp",    
                    "test2": "nya"
                },
                "id": "test2",
                "url": "/blog/test2"
            }
        ]
    }
    */

    // Extract the posts
    list.value = blog_list.posts

    // Extract the tags
    tagList.value = blog_list.posts.flatMap(post => post.metadata.tags).filter((tag, index, self) => self.indexOf(tag) === index)

    // Sort the posts by date, most recent first
    list.value.sort((a, b) => new Date(b.metadata.date) - new Date(a.metadata.date))
}
fetchList()

function resetReadingPosition() {
    window.scrollTo(0, 0)
}

// Hook and check if the URL gets changed in the query params
watch(url, async () => {
    await fetchData(url.value)
}, {
    immediate: true
});

</script>

<template>
    <div class="relative z-50 flex w-full justify-center text-white">
        <div class="mt-8 flex-col text-center">
            <Transition name="list">
            <div v-if="url == null" :key="url">
                <h1>Blog</h1>
                <div class="flex justify-center m-5">
                    <div v-for="tag in tagList" :key="tag" class="m-1 text-center">
                        <button
                            @click="tagFilter.includes(tag) ? tagFilter.splice(tagFilter.indexOf(tag), 1) : tagFilter.push(tag)"
                            class="text-xs bg-black border-purple-400 border text-white p-1 rounded-md"
                            :class="tagFilter.includes(tag) ? 'border-2 border-white bg-slate-700' : 'border-2 bg-black text-white'">{{
                                tag }}</button>
                    </div>
                </div>
                <div>
                    <TransitionGroup name="list">
                        <div v-for="post in tagFilter.length == 0 ? list : list.filter(post => tagFilter.some(tag => post.metadata.tags.includes(tag)))" :key="post.id">
                            <PostCard :url="post.url" :key="post.id" :tagFilter="tagFilter"/>
                        </div>
                    </TransitionGroup>
                </div>
            </div>
            <div v-else>
                <Transition name="list">
                    <div class="flex flex-col" :key="url">
                        <h1>{{ title }}</h1>
                        <small>{{ date }}</small>
                        <div class="max-w-50 flex flex-row justify-center">
                            <div v-for="tag in tags" :key="tag" class="m-1 text-center">
                                <span class="text-xs bg-black border-purple-400 border-2 text-white p-1 rounded-md">{{
                                    tag }}</span>
                            </div>
                        </div>
                        <div>
                            <!-- Next/Prev controls, on the left and right side using PostCards -->
                            <div class="flex max-w-4xl max-md:w-screen">
                                <div class="justify-start">
                                    <NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous" class="m-2 text-white">Previous</NuxtLink>
                                </div>
                                <div class="justify-end">
                                    <NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next" class="m-2 text-white">Next</NuxtLink>
                                </div>
                            </div>
                        </div>
                        <Card class="text-pretty max-w-4xl mt-4 max-md:w-screen text-left">
                            <Markdown :text="text"></Markdown>
                            <!-- Aligned next/prev controls -->
                            <div class="flex">
                                <div class="justify-start">
                                    <NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous" class="m-2 text-white">Previous</NuxtLink>
                                </div>
                                <div class="justify-end">
                                    <NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next" class="m-2 text-white">Next</NuxtLink>
                                </div>
                            </div>
                        </Card>
                    </div>
                </Transition>
            </div>
        </Transition>
        </div>
    </div>
</template>

<style scoped>
.list-move,
.list-enter-active,
.list-leave-active {
    transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

.list-enter-from,
.list-leave-to {
    opacity: 0;
    transform: translate(100px, 0);
}

.list-leave-active {
    position: absolute;
}
</style>