<template>
    <Teleport to="#teleports" v-if="display && (!fetched || loaded)">
        <div class="absolute border-2 border-light-35 dark:border-dark-35 max-w-[550px] max-h-[450px] overflow-auto bg-light-0 dark:bg-dark-0 text-light-100 dark:text-dark-100" :class="{'is-loaded': fetched}" :style="pos"
            @mouseenter="debounce(show, 250)" @mouseleave="debounce(() => display = false, 250)">
            <div v-if="pending" class="loading"></div>
            <template v-else-if="content !==''">
                <div v-if="type === 'Markdown'" class="p-6">
                    <ProseH1>{{ title }}</ProseH1>
                    <Markdown v-model="content"></Markdown>
                </div>
                <div v-else-if="type === 'Canvas'" class="">
                    <CanvasRenderer :canvas="JSON.parse(content) " />
                </div>
                <div class="h-100 w-100 flex flex-1 flex-col justify-center items-center" v-else>
                    <div class="text-3xl font-extralight tracking-wide text-light-60 dark:text-dark-60">Fichier vide</div>
                    <div class="text-lg text-light-60 dark:text-dark-60">Cette page est vide</div>
                </div>
            </template>
            <div class="h-100 w-100 flex flex-1 flex-col justify-center items-center" v-else>
                <div class="text-3xl font-extralight tracking-wide text-light-60 dark:text-dark-60">Impossible d'afficher</div>
                <div class="text-lg text-light-60 dark:text-dark-60">Cette page est impossible à traiter</div>
            </div>
        </div>
    </Teleport>
    <span ref="el" @mouseenter="debounce(show, 250)" @mouseleave="debounce(() => display = false, 250)">
        <slot></slot>
    </span>
</template>

<script setup lang="ts">

const props = defineProps({
    project: {
        type: Number,
        required: true,
    },
    path: {
        type: String,
        required: true,
    },
    anchor: {
        type: String,
        required: false,
    }
})
const content = ref(''), title = ref(''), type = ref(''), display = ref(false), pending = ref(false), fetched = ref(false);
const el = ref(), pos = ref<Record<string, string>>();
const loaded = computed(() => !pending.value && fetched.value && content.value !== '');

async function fetch()
{
    fetched.value = true;
    pending.value = true;

    const data = await $fetch(`/api/project/${props.project}/file`, {
        method: 'get',
        query: {
            path: props.path,
        },
    });

    pending.value = false;

    if(data && data[0])
    {
        content.value = data[0].content;
        title.value = data[0].title;
        type.value = data[0].type;
    }
}
async function show()
{
    if(display.value)
        return;

    if(!fetched.value)
        await fetch();

    const rect = (el.value as HTMLDivElement)?.getBoundingClientRect();

    if(!rect)
        return;

    const r: Record<string, string> = {};
    if (rect.bottom + 450 < window.innerHeight)
        r.top = (rect.bottom + 4) + "px";
    else
        r.bottom = (window.innerHeight - rect.top + 4) + "px";
    if (rect.right + 550 < window.innerWidth)
        r.left = rect.left + "px";
    else
        r.right = (window.innerWidth - rect.right + 4) + "px";

    pos.value = r;
    display.value = true;
}
let debounceFn: () => void, timeout: NodeJS.Timeout;
function debounce(fn: () => void, ms: number)
{
    debounceFn = fn;
    clearTimeout(timeout);
    timeout = setTimeout(debounceFn, ms);
}
</script>