<script setup lang="ts">
import { useDropZone } from '@vueuse/core';
import { toast } from 'vue-sonner';
import DirectoryListContextMenu from '~/components/DirectoryListContextMenu.vue';
import RenameEntryDialog from '~/components/actions/RenameEntryDialog.vue';
import { fetchFile, getWarrenDirectory } from '~/lib/api/warrens';
import type { DirectoryEntry } from '~/shared/types';

definePageMeta({
    middleware: ['authenticated'],
});

const warrenStore = useWarrenStore();
const loadingIndicator = useLoadingIndicator();
const uploadStore = useUploadStore();
const warrenPath = computed(() => useWarrenPath());

const dropZoneRef = ref<HTMLElement>();

const dropZone = useDropZone(dropZoneRef, {
    onDrop,
    multiple: true,
});

if (warrenStore.current == null) {
    await navigateTo({
        path: '/warrens',
    });
}

const dirData = useAsyncData(
    'current-directory',
    async () => {
        if (warrenStore.current == null) {
            return {
                files: [],
                parent: null,
            };
        }

        loadingIndicator.start();
        warrenStore.loading = true;

        const { files, parent } = await getWarrenDirectory(
            warrenStore.current.warrenId,
            warrenStore.current.path
        );

        warrenStore.loading = false;
        loadingIndicator.finish();

        return { files, parent };
    },
    { watch: [warrenPath] }
).data;

function onDrop(files: File[] | null, e: DragEvent) {
    if (files == null) {
        return;
    }

    e.preventDefault();

    if (warrenStore.current == null) {
        toast.warning('Upload', {
            description: 'Enter a warren before attempting to upload files',
        });
        return;
    }

    const added = uploadStore.addFiles(
        warrenStore.current.warrenId,
        warrenStore.current.path,
        files
    );

    if (added) {
        uploadStore.dialogOpen = true;
    }
}

async function onEntryClicked(entry: DirectoryEntry) {
    if (warrenStore.loading || warrenStore.current == null) {
        return;
    }

    if (entry.fileType === 'directory') {
        warrenStore.addToCurrentWarrenPath(entry.name);
        return;
    }

    if (entry.mimeType == null) {
        return;
    }

    if (entry.mimeType.startsWith('image/')) {
        const result = await fetchFile(
            warrenStore.current.warrenId,
            warrenStore.current.path,
            entry.name
        );
        if (result.success) {
            const url = URL.createObjectURL(result.data);
            warrenStore.imageViewer.src = url;
        }
    }
}

function onEntryDownload(entry: DirectoryEntry) {
    if (warrenStore.current == null) {
        return;
    }

    const downloadName =
        entry.fileType === 'directory' ? `${entry.name}.zip` : entry.name;
    const downloadApiUrl = getApiUrl(
        `warrens/files/cat?warrenId=${warrenStore.current.warrenId}&path=${joinPaths(warrenStore.current.path, entry.name)}`
    );

    downloadFile(downloadName, downloadApiUrl);
}

function onBack() {
    warrenStore.backCurrentPath();
}
</script>

<template>
    <div ref="dropZoneRef" class="grow">
        <DirectoryListContextMenu class="w-full grow">
            <DirectoryList
                v-if="dirData != null"
                :is-over-drop-zone="
                    dropZone.isOverDropZone.value &&
                    dropZone.files.value != null
                "
                :entries="dirData.files"
                :parent="dirData.parent"
                @entry-click="onEntryClicked"
                @entry-download="onEntryDownload"
                @back="onBack"
            />
        </DirectoryListContextMenu>
        <RenameEntryDialog />
    </div>
</template>
