<script setup lang="ts">
import {
    ContextMenu,
    ContextMenuTrigger,
    ContextMenuContent,
    ContextMenuItem,
    ContextMenuSeparator,
} from '@/components/ui/context-menu';
import {
    deleteWarrenDirectory,
    deleteWarrenFile,
    fetchFile,
} from '~/lib/api/warrens';
import type { DirectoryEntry } from '#shared/types';
import { toast } from 'vue-sonner';

const warrenStore = useWarrenStore();
const copyStore = useCopyStore();
const renameDialog = useRenameDirectoryDialog();

const { entry, disabled } = defineProps<{
    entry: DirectoryEntry;
    disabled: boolean;
}>();

const deleting = ref(false);
const isCopied = computed(
    () =>
        warrenStore.current != null &&
        copyStore.file != null &&
        warrenStore.current.warrenId === copyStore.file.warrenId &&
        warrenStore.current.path === copyStore.file.path &&
        entry.name === copyStore.file.name
);

async function submitDelete(force: boolean = false) {
    if (warrenStore.current == null) {
        return;
    }

    deleting.value = true;

    if (entry.fileType === 'directory') {
        await deleteWarrenDirectory(
            warrenStore.current.warrenId,
            warrenStore.current.path,
            entry.name,
            force
        );
    } else {
        await deleteWarrenFile(
            warrenStore.current.warrenId,
            warrenStore.current.path,
            entry.name
        );
    }

    deleting.value = false;
}

async function openRenameDialog() {
    renameDialog.openDialog(entry);
}

async function onClick() {
    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 onDragStart(e: DragEvent) {
    if (e.dataTransfer == null) {
        return;
    }

    e.dataTransfer.setData('application/warren', entry.name);
    e.dataTransfer.dropEffect = 'move';
}

const onDrop = onDirectoryEntryDrop(entry);

function onCopy() {
    if (warrenStore.current == null) {
        return;
    }

    copyStore.copyFile(
        warrenStore.current.warrenId,
        warrenStore.current.path,
        entry.name
    );
}

async function onDownload() {
    if (warrenStore.current == null) {
        return;
    }

    if (entry.fileType !== 'file') {
        toast.warning('Download', {
            description: 'Directory downloads are not supported yet',
        });
        return;
    }

    const anchor = document.createElement('a');

    anchor.download = entry.name;
    anchor.href = getApiUrl(
        `warrens/files/cat?warrenId=${warrenStore.current.warrenId}&path=${joinPaths(warrenStore.current.path, entry.name)}`
    );
    anchor.rel = 'noopener';
    anchor.target = '_blank';

    anchor.click();
}
</script>

<template>
    <ContextMenu>
        <ContextMenuTrigger>
            <button
                :disabled="warrenStore.loading || disabled"
                :class="[
                    'bg-accent/30 border-border flex w-52 translate-0 flex-row gap-4 overflow-hidden rounded-md border-1 px-4 py-2 select-none',
                    isCopied && 'border-primary/50 border',
                ]"
                draggable="true"
                @dragstart="onDragStart"
                @drop="onDrop"
                @click="onClick"
            >
                <div class="flex flex-row items-center">
                    <Icon
                        v-if="
                            entry.fileType !== 'file' ||
                            entry.mimeType == null ||
                            !entry.mimeType.startsWith('image/')
                        "
                        class="size-6"
                        :name="
                            entry.fileType === 'file'
                                ? getFileIcon(entry.mimeType)
                                : 'lucide:folder'
                        "
                    />
                    <object
                        v-else
                        :type="entry.mimeType"
                        class="size-6 object-cover"
                        width="24"
                        height="24"
                        :data="
                            getApiUrl(
                                `warrens/files/cat?warrenId=${warrenStore.current!.warrenId}&path=${joinPaths(warrenStore.current!.path, entry.name)}`
                            )
                        "
                    >
                        <Icon
                            class="size-6"
                            :name="getFileIcon(entry.mimeType)"
                        />
                    </object>
                </div>

                <div
                    class="flex w-full flex-col items-start justify-stretch gap-0 overflow-hidden text-left leading-6"
                >
                    <span class="w-full truncate">{{ entry.name }}</span>
                    <NuxtTime
                        v-if="entry.createdAt != null"
                        :datetime="entry.createdAt * 1000"
                        class="text-muted-foreground w-full truncate text-sm"
                        relative
                    ></NuxtTime>
                </div>
            </button>
        </ContextMenuTrigger>
        <ContextMenuContent>
            <ContextMenuItem @select="openRenameDialog">
                <Icon name="lucide:pencil" />
                Rename
            </ContextMenuItem>
            <ContextMenuItem @select="onCopy">
                <Icon name="lucide:copy" />
                Copy
            </ContextMenuItem>
            <ContextMenuItem
                :disabled="entry.fileType !== 'file'"
                @select="onDownload"
            >
                <Icon name="lucide:download" />
                Download
            </ContextMenuItem>

            <ContextMenuSeparator />

            <ContextMenuItem @select="() => submitDelete(false)">
                <Icon name="lucide:trash-2" />
                Delete
            </ContextMenuItem>
            <ContextMenuItem
                v-if="entry.fileType === 'directory'"
                @select="() => submitDelete(true)"
            >
                <Icon
                    class="text-destructive-foreground"
                    name="lucide:trash-2"
                />
                Force delete
            </ContextMenuItem>
        </ContextMenuContent>
    </ContextMenu>
</template>
