<script setup lang="ts">
import Outline from '@/components/ui/outline/Outline.vue';
import SidebarTrigger from '@/components/ui/sidebar/SidebarTrigger.vue';
import Empty from '@/components/ui/empty/Empty.vue';
import UploadEntry from '@/components/internal/import/uploadentry/UploadEntry.vue';
import EmptyHeader from '@/components/ui/empty/EmptyHeader.vue';
import EmptyMedia from '@/components/ui/empty/EmptyMedia.vue';
import EmptyTitle from '@/components/ui/empty/EmptyTitle.vue';
import EmptyDescription from '@/components/ui/empty/EmptyDescription.vue';

import { Download, MegaphoneOff, Play } from 'lucide-vue-next';
import type { EventSourceListener } from '~/composeables/api/event-source';
import type { StreamProgress200Item } from '~/composeables/api/models';
import { streamProgress } from '~/composeables/api/progress-sse-controller/progress-sse-controller';
import { useCurrentPlaylistStore } from '~/stores/use-current-playlist-store';

const currentPlaylistStore = useCurrentPlaylistStore();
const progressEntries = ref<Map<string, StreamProgress200Item>>(new Map());
let listener: EventSourceListener<StreamProgress200Item> | null = null;

const sortedProgressEntries = computed(() => {
    return Array.from(progressEntries.value.values())
        .sort((a, b) => {
            const timeA = a.timestamp || 0;
            const timeB = b.timestamp || 0;
            return timeB - timeA;
        });
});

const unwatch = watch(() => currentPlaylistStore.id, (newId, oldId) => {
    if (newId !== -1 && newId !== oldId) {
        listenImports();
    } else if (newId === -1) {
        stopImports();
    }
}, { immediate: true });

const updateEntryFromProgress = (data: StreamProgress200Item) => {
    if (!data.trackSourceId)
        return;
    progressEntries.value = new Map(progressEntries.value);
    progressEntries.value.set(data.id!.toString(), data);
}

async function listenImports() {
    if (listener) {
        listener.close();
    }
    streamProgress(currentPlaylistStore.id).then(listener => {
        listener.handle(data => {
            updateEntryFromProgress(data);
        })
    }).catch(err => {
        console.error(err);
    })
}

function stopImports() {
    if (listener) {
        listener.close();
        listener = null;
    }
}

onUnmounted(() => {
    stopImports();
    unwatch();
});
</script>

<template>
    <div class="flex-1">
        <NuxtLayout name="default">
            <template #header>
                <Outline side="bottom" padding="dense" class="w-full">
                    <div class="flex gap-8 w-full items-center">
                        <SidebarTrigger :size="5" />
                        <h2 class="scroll-m-20 text-3xl font-semibold tracking-tight transition-colors first:mt-0">
                            Import tracks
                        </h2>
                    </div>
                </Outline>
            </template>
            <div class="w-full flex flex-col p-8">
                <Outline class="rounded-xl bg-muted flex flex-col items-center justify-center gap-1">
                    <Download />
                    <h4 class="scroll-m-20 text-xl font-semibold tracking-tight">
                        Drag and drop your audio files
                    </h4>
                    <p class="text-sm text-muted-foreground">
                        or
                    </p>
                    <Button variant="destructive">
                        <Play />
                        From Youtube
                    </Button>
                </Outline>
                <div>
                    <h3 class="scroll-m-20 text-2xl font-semibold tracking-tight">
                        Uploaded files
                    </h3>
                    <div class="space-y-2">
                        <UploadEntry v-for="entry in sortedProgressEntries" :key="entry.id" :entry="entry" />
                        <Empty class="border border-dashed" v-if="progressEntries.size === 0">
                            <EmptyHeader>
                                <EmptyMedia variant="icon">
                                    <MegaphoneOff />
                                </EmptyMedia>
                                <EmptyTitle>No imports found</EmptyTitle>
                                <EmptyDescription>
                                    Upload any track to see their progress.
                                </EmptyDescription>
                            </EmptyHeader>
                        </Empty>
                    </div>
                </div>
            </div>
        </NuxtLayout>
    </div>
</template>
