<script lang="ts">
	import { getContext } from "svelte";
	import { goto } from "$app/navigation";
	import {
		Button,
		Modal,
		Input,
	} from "$lib/components/ui";
	import { DocumentViewer } from "$lib/components/documents";
	import { createLogger } from "$lib/utils/logger";
	import { toasts } from "$lib/stores/toast.svelte";
	import type { Document } from "$lib/supabase/types";
	import type { SupabaseClient } from "@supabase/supabase-js";
	import type { Database } from "$lib/supabase/types";
	import * as m from "$lib/paraglide/messages";
	import { logActivity } from "$lib/api/activity";
	import {
		moveDocument,
		updateDocument,
		deleteDocument,
		createDocument,
		copyDocument,
	} from "$lib/api/documents";

	const log = createLogger("component.file-browser");

	interface Props {
		org: { id: string; name: string; slug: string };
		documents: Document[];
		currentFolderId: string | null;
		user: { id: string } | null;
		/** Page title shown in the header */
		title?: string;
	}

	let {
		org,
		documents = $bindable(),
		currentFolderId,
		user,
		title = m.files_title(),
	}: Props = $props();

	const supabase = getContext<SupabaseClient<Database>>("supabase");

	let selectedDoc = $state<Document | null>(null);
	let showCreateModal = $state(false);
	let showEditModal = $state(false);
	let editingDoc = $state<Document | null>(null);
	let newDocName = $state("");
	let newDocType = $state<"folder" | "document" | "kanban">("document");
	let viewMode = $state<"list" | "grid">(
		typeof localStorage !== "undefined" &&
			localStorage.getItem("root:viewMode") === "list"
			? "list"
			: "grid",
	);

	function toggleViewMode() {
		viewMode = viewMode === "list" ? "grid" : "list";
		if (typeof localStorage !== "undefined") {
			localStorage.setItem("root:viewMode", viewMode);
		}
	}

	// Context menu state
	let contextMenu = $state<{ x: number; y: number; doc: Document } | null>(
		null,
	);
	let showOrganizeMenu = $state(false);

	// Sort: folders first, then documents, then kanbans, alphabetical
	function typeOrder(type: string): number {
		if (type === "folder") return 0;
		if (type === "document") return 1;
		if (type === "kanban") return 2;
		return 3;
	}

	const currentFolderItems = $derived(
		documents
			.filter((d) =>
				currentFolderId === null
					? d.parent_id === null
					: d.parent_id === currentFolderId,
			)
			.sort((a, b) => {
				const typeA = typeOrder(a.type);
				const typeB = typeOrder(b.type);
				if (typeA !== typeB) return typeA - typeB;
				return a.name.localeCompare(b.name);
			}),
	);

	// Drag and drop state
	let draggedItem = $state<Document | null>(null);
	let dragOverFolder = $state<string | null>(null);
	let isDragging = $state(false);
	let dragOverBreadcrumb = $state<string | null | undefined>(undefined);

	// Build breadcrumb path
	const breadcrumbPath = $derived.by(() => {
		const path: { id: string | null; name: string }[] = [
			{ id: null, name: "Home" },
		];
		if (currentFolderId === null) return path;

		let current = documents.find((d) => d.id === currentFolderId);
		const ancestors: { id: string; name: string }[] = [];
		while (current) {
			ancestors.unshift({ id: current.id, name: current.name });
			current = current.parent_id
				? documents.find((d) => d.id === current!.parent_id)
				: undefined;
		}
		return [...path, ...ancestors];
	});

	// URL helpers
	function getFolderUrl(folderId: string | null): string {
		if (!folderId) return `/${org.slug}/documents`;
		return `/${org.slug}/documents/folder/${folderId}`;
	}

	function getFileUrl(doc: Document): string {
		return `/${org.slug}/documents/file/${doc.id}`;
	}

	function getDocIcon(doc: Document): string {
		if (doc.type === "folder") return "folder";
		if (doc.type === "kanban") return "view_kanban";
		return "description";
	}

	function handleItemClick(doc: Document) {
		if (isDragging) {
			isDragging = false;
			return;
		}
		if (doc.type === "folder") {
			goto(getFolderUrl(doc.id));
		} else if (doc.type === "kanban") {
			goto(getFileUrl(doc));
		} else {
			selectedDoc = doc;
		}
	}

	function handleDoubleClick(doc: Document) {
		if (doc.type === "folder") {
			window.open(getFolderUrl(doc.id), "_blank");
		} else {
			window.open(getFileUrl(doc), "_blank");
		}
	}

	function handleAuxClick(e: MouseEvent, doc: Document) {
		if (e.button === 1) {
			e.preventDefault();
			if (doc.type === "folder") {
				window.open(getFolderUrl(doc.id), "_blank");
			} else {
				window.open(getFileUrl(doc), "_blank");
			}
		}
	}

	// Context menu handlers
	function handleContextMenu(e: MouseEvent, doc: Document) {
		e.preventDefault();
		contextMenu = { x: e.clientX, y: e.clientY, doc };
		showOrganizeMenu = false;
	}

	function closeContextMenu() {
		contextMenu = null;
		showOrganizeMenu = false;
	}

	function contextRename() {
		if (!contextMenu) return;
		editingDoc = contextMenu.doc;
		newDocName = contextMenu.doc.name;
		showEditModal = true;
		closeContextMenu();
	}

	async function contextCopy() {
		if (!contextMenu || !user) return;
		const doc = contextMenu.doc;
		closeContextMenu();
		try {
			const newDoc = await copyDocument(supabase, doc, org.id, user.id);
			documents = [...documents, newDoc];
			toasts.success(`Copied "${doc.name}"`);
		} catch {
			toasts.error("Failed to copy document");
		}
	}

	function contextOrganize() {
		showOrganizeMenu = !showOrganizeMenu;
	}

	async function contextMoveToFolder(folderId: string | null) {
		if (!contextMenu) return;
		const doc = contextMenu.doc;
		closeContextMenu();
		await handleMove(doc.id, folderId);
		toasts.success(
			`Moved "${doc.name}" to ${folderId ? (documents.find((d) => d.id === folderId)?.name ?? "folder") : "Home"}`,
		);
	}

	function contextDelete() {
		if (!contextMenu) return;
		const doc = contextMenu.doc;
		closeContextMenu();
		handleDelete(doc);
	}

	const availableFolders = $derived(
		documents.filter(
			(d) => d.type === "folder" && d.id !== contextMenu?.doc.id,
		),
	);

	function handleAdd() {
		showCreateModal = true;
	}

	// Drag handlers
	function handleDragStart(e: DragEvent, doc: Document) {
		isDragging = true;
		draggedItem = doc;
		if (e.dataTransfer) {
			e.dataTransfer.effectAllowed = "move";
			e.dataTransfer.setData("text/plain", doc.id);
		}
	}

	function handleDragEnd() {
		resetDragState();
	}

	function handleDragOver(e: DragEvent, doc: Document) {
		e.preventDefault();
		e.stopPropagation();
		if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
		if (draggedItem?.id === doc.id) return;
		if (doc.type === "folder") {
			dragOverFolder = doc.id;
		} else {
			dragOverFolder = null;
		}
	}

	function handleDragLeave() {
		dragOverFolder = null;
	}

	async function handleDrop(e: DragEvent, targetDoc: Document) {
		e.preventDefault();
		e.stopPropagation();
		if (!draggedItem || draggedItem.id === targetDoc.id) {
			resetDragState();
			return;
		}
		if (targetDoc.type === "folder") {
			const draggedName = draggedItem.name;
			await handleMove(draggedItem.id, targetDoc.id);
			toasts.success(`Moved "${draggedName}" into "${targetDoc.name}"`);
		}
		resetDragState();
	}

	function handleContainerDragOver(e: DragEvent) {
		e.preventDefault();
		if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
	}

	async function handleDropOnEmpty(e: DragEvent) {
		e.preventDefault();
		if (!draggedItem) return;
		if (draggedItem.parent_id !== currentFolderId) {
			await handleMove(draggedItem.id, currentFolderId);
		}
		resetDragState();
	}

	function resetDragState() {
		draggedItem = null;
		dragOverFolder = null;
		setTimeout(() => {
			isDragging = false;
		}, 100);
	}

	async function handleMove(docId: string, newParentId: string | null) {
		documents = documents.map((d) =>
			d.id === docId ? { ...d, parent_id: newParentId } : d,
		);
		try {
			await moveDocument(supabase, docId, newParentId);
		} catch {
			toasts.error("Failed to move file");
			const { data: freshDocs } = await supabase
				.from("documents")
				.select(
					"id, name, type, parent_id, path, position, created_at, updated_at, created_by, org_id",
				)
				.eq("org_id", org.id)
				.order("name");
			if (freshDocs) documents = freshDocs as Document[];
		}
	}

	async function handleCreate() {
		if (!newDocName.trim() || !user) return;

		try {
			if (newDocType === "kanban") {
				// Create kanban board first, then link as document
				const { data: newBoard, error: boardError } = await supabase
					.from("kanban_boards")
					.insert({ org_id: org.id, name: newDocName })
					.select()
					.single();
				if (boardError || !newBoard) {
					toasts.error("Failed to create kanban board");
					return;
				}
				await supabase.from("kanban_columns").insert([
					{ board_id: newBoard.id, name: "To Do", position: 0 },
					{ board_id: newBoard.id, name: "In Progress", position: 1 },
					{ board_id: newBoard.id, name: "Done", position: 2 },
				]);
				const newDoc = await createDocument(
					supabase,
					org.id,
					newDocName,
					"kanban",
					currentFolderId,
					user.id,
					{
						id: newBoard.id,
						content: {
							type: "kanban",
							board_id: newBoard.id,
						} as import("$lib/supabase/types").Json,
					},
				);
				logActivity(supabase, {
					orgId: org.id,
					userId: user.id,
					action: "create",
					entityType: "kanban_board",
					entityId: newDoc.id,
					entityName: newDocName,
				});
				goto(getFileUrl(newDoc));
			} else {
				const newDoc = await createDocument(
					supabase,
					org.id,
					newDocName,
					newDocType,
					currentFolderId,
					user.id,
				);
				documents = [...documents, newDoc];
				logActivity(supabase, {
					orgId: org.id,
					userId: user.id,
					action: "create",
					entityType: newDocType === "folder" ? "folder" : "document",
					entityId: newDoc.id,
					entityName: newDocName,
				});
				if (newDocType === "document") {
					goto(getFileUrl(newDoc));
				}
			}
		} catch {
			toasts.error("Failed to create document");
		}

		showCreateModal = false;
		newDocName = "";
		newDocType = "document";
	}

	async function handleSave(content: import("$lib/supabase/types").Json) {
		if (!selectedDoc) return;
		try {
			await updateDocument(supabase, selectedDoc.id, { content });
			documents = documents.map((d) =>
				d.id === selectedDoc!.id ? { ...d, content } : d,
			);
		} catch {
			toasts.error("Failed to save document");
		}
	}

	async function handleRename() {
		if (!editingDoc || !newDocName.trim()) return;
		try {
			await updateDocument(supabase, editingDoc.id, { name: newDocName });
			if (user) {
				logActivity(supabase, {
					orgId: org.id,
					userId: user.id,
					action: "rename",
					entityType:
						editingDoc.type === "folder" ? "folder" : "document",
					entityId: editingDoc.id,
					entityName: newDocName,
				});
			}
			documents = documents.map((d) =>
				d.id === editingDoc!.id ? { ...d, name: newDocName } : d,
			);
			if (selectedDoc?.id === editingDoc.id) {
				selectedDoc = { ...selectedDoc, name: newDocName };
			}
		} catch {
			toasts.error("Failed to rename document");
		}
		showEditModal = false;
		editingDoc = null;
		newDocName = "";
	}

	async function handleDelete(doc: Document) {
		const itemType =
			doc.type === "folder" ? "folder and all its contents" : "document";
		if (!confirm(`Delete this ${itemType}?`)) return;

		// Recursively collect all descendant IDs for proper deletion
		function collectDescendantIds(parentId: string): string[] {
			const children = documents.filter((d) => d.parent_id === parentId);
			let ids: string[] = [];
			for (const child of children) {
				ids.push(child.id);
				if (child.type === "folder") {
					ids = ids.concat(collectDescendantIds(child.id));
				}
			}
			return ids;
		}

		try {
			if (doc.type === "folder") {
				const descendantIds = collectDescendantIds(doc.id);
				for (const id of descendantIds) {
					await deleteDocument(supabase, id);
				}
			}
			await deleteDocument(supabase, doc.id);

			if (user) {
				logActivity(supabase, {
					orgId: org.id,
					userId: user.id,
					action: "delete",
					entityType:
						doc.type === "folder"
							? "folder"
							: doc.type === "kanban"
								? "kanban_board"
								: "document",
					entityId: doc.id,
					entityName: doc.name,
				});
			}
			const deletedIds = new Set([
				doc.id,
				...(doc.type === "folder" ? collectDescendantIds(doc.id) : []),
			]);
			documents = documents.filter((d) => !deletedIds.has(d.id));
			if (selectedDoc?.id === doc.id) {
				selectedDoc = null;
			}
		} catch {
			toasts.error("Failed to delete document");
		}
	}
</script>

<div class="flex h-full gap-0">
	<!-- Files Panel -->
	<div class="flex flex-col flex-1 min-w-0 h-full overflow-hidden">
		<!-- Toolbar: Breadcrumbs + Actions -->
		<div class="flex items-center gap-2 px-6 py-3 border-b border-light/5 shrink-0">
			<!-- Breadcrumb Path -->
			<nav class="flex items-center gap-1 flex-1 min-w-0 overflow-x-auto">
				{#each breadcrumbPath as crumb, i}
					{#if i > 0}
						<span
							class="material-symbols-rounded text-light/20 shrink-0"
							style="font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 18;"
						>
							chevron_right
						</span>
					{/if}
					<a
						href={getFolderUrl(crumb.id)}
						class="px-2 py-1 rounded-lg text-body-sm font-body whitespace-nowrap transition-colors
						{crumb.id === currentFolderId
							? 'text-white bg-dark/30'
							: 'text-light/50 hover:text-white hover:bg-dark/30'}
						{dragOverBreadcrumb === (crumb.id ?? '__root__')
							? 'ring-2 ring-primary bg-primary/10'
							: ''}"
						ondragover={(e) => {
							e.preventDefault();
							e.stopPropagation();
							if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
							dragOverBreadcrumb = crumb.id ?? "__root__";
						}}
						ondragleave={() => {
							dragOverBreadcrumb = undefined;
						}}
						ondrop={async (e) => {
							e.preventDefault();
							e.stopPropagation();
							dragOverBreadcrumb = undefined;
							if (!draggedItem) return;
							if (draggedItem.parent_id === crumb.id) {
								resetDragState();
								return;
							}
							const draggedName = draggedItem.name;
							await handleMove(draggedItem.id, crumb.id);
							toasts.success(
								`Moved "${draggedName}" to "${crumb.name}"`,
							);
							resetDragState();
						}}
					>
						{#if i === 0}
							<span class="material-symbols-rounded" style="font-size: 16px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 16;">home</span>
						{:else}
							{crumb.name}
						{/if}
					</a>
				{/each}
			</nav>

			<Button size="sm" icon="add" onclick={handleAdd}>{m.btn_new()}</Button>
			<button
				type="button"
				class="p-1.5 rounded-lg text-light/40 hover:text-white hover:bg-dark/50 transition-colors"
				title={m.files_toggle_view()}
				onclick={toggleViewMode}
			>
				<span
					class="material-symbols-rounded"
					style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
					>{viewMode === "list" ? "grid_view" : "view_list"}</span
				>
			</button>
		</div>

		<!-- File List/Grid -->
		<div class="flex-1 overflow-auto min-h-0 p-4">
			{#if viewMode === "list"}
				<div
					class="flex flex-col gap-0.5"
					ondragover={handleContainerDragOver}
					ondrop={handleDropOnEmpty}
					role="list"
				>
					{#if currentFolderItems.length === 0}
						<div class="flex flex-col items-center justify-center text-light/40 py-16">
							<span class="material-symbols-rounded mb-3" style="font-size: 48px; font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 48;">folder_open</span>
							<p class="text-body-sm">{m.files_empty()}</p>
						</div>
					{:else}
						{#each currentFolderItems as item}
							<button
								type="button"
								class="flex items-center gap-3 px-3 py-2 rounded-xl w-full text-left transition-colors hover:bg-dark/50
								{selectedDoc?.id === item.id ? 'bg-dark/50 ring-1 ring-primary/20' : ''}
								{draggedItem?.id === item.id ? 'opacity-50' : ''}
								{dragOverFolder === item.id ? 'ring-2 ring-primary bg-primary/10' : ''}"
								draggable="true"
								ondragstart={(e) => handleDragStart(e, item)}
								ondragend={handleDragEnd}
								ondragover={(e) => handleDragOver(e, item)}
								ondragleave={handleDragLeave}
								ondrop={(e) => handleDrop(e, item)}
								onclick={() => handleItemClick(item)}
								ondblclick={() => handleDoubleClick(item)}
								onauxclick={(e) => handleAuxClick(e, item)}
								oncontextmenu={(e) =>
									handleContextMenu(e, item)}
							>
								<span
									class="material-symbols-rounded shrink-0 {item.type === 'folder' ? 'text-amber-400' : item.type === 'kanban' ? 'text-purple-400' : 'text-light/50'}"
									style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
								>
									{getDocIcon(item)}
								</span>
								<span
									class="font-body text-body-sm text-white truncate flex-1"
									>{item.name}</span
								>
								{#if item.type === "folder"}
									<span
										class="material-symbols-rounded text-light/20"
										style="font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 18;"
									>
										chevron_right
									</span>
								{/if}
							</button>
						{/each}
					{/if}
				</div>
			{:else}
				<!-- Grid View -->
				<div
					class="grid grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-2"
					ondragover={handleContainerDragOver}
					ondrop={handleDropOnEmpty}
					role="list"
				>
					{#if currentFolderItems.length === 0}
						<div class="col-span-full flex flex-col items-center justify-center text-light/40 py-16">
							<span class="material-symbols-rounded mb-3" style="font-size: 48px; font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 48;">folder_open</span>
							<p class="text-body-sm">{m.files_empty()}</p>
						</div>
					{:else}
						{#each currentFolderItems as item}
							<button
								type="button"
								class="flex flex-col items-center gap-2 p-3 rounded-xl border border-transparent transition-all hover:bg-dark/50 hover:border-light/5
								{selectedDoc?.id === item.id ? 'bg-dark/50 border-primary/20' : ''}
								{draggedItem?.id === item.id ? 'opacity-50' : ''}
								{dragOverFolder === item.id ? 'ring-2 ring-primary bg-primary/10' : ''}"
								draggable="true"
								ondragstart={(e) => handleDragStart(e, item)}
								ondragend={handleDragEnd}
								ondragover={(e) => handleDragOver(e, item)}
								ondragleave={handleDragLeave}
								ondrop={(e) => handleDrop(e, item)}
								onclick={() => handleItemClick(item)}
								ondblclick={() => handleDoubleClick(item)}
								onauxclick={(e) => handleAuxClick(e, item)}
								oncontextmenu={(e) =>
									handleContextMenu(e, item)}
							>
								<span
									class="material-symbols-rounded {item.type === 'folder' ? 'text-amber-400' : item.type === 'kanban' ? 'text-purple-400' : 'text-light/40'}"
									style="font-size: 40px; font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 40;"
								>
									{getDocIcon(item)}
								</span>
								<span
									class="font-body text-[12px] text-white text-center truncate w-full"
									>{item.name}</span
								>
							</button>
						{/each}
					{/if}
				</div>
			{/if}
		</div>
	</div>

	<!-- Compact Editor Panel (shown when a doc is selected) -->
	{#if selectedDoc}
		<div class="flex-1 min-w-0 h-full border-l border-light/5">
			<DocumentViewer
				document={selectedDoc}
				onSave={handleSave}
				mode="preview"
				editUrl={getFileUrl(selectedDoc)}
			/>
		</div>
	{/if}
</div>

<Modal
	isOpen={showCreateModal}
	onClose={() => (showCreateModal = false)}
	title={m.files_create_title()}
>
	<div class="space-y-4">
		<div class="flex gap-2">
			<button
				type="button"
				class="flex-1 py-2 px-4 rounded-lg border transition-colors {newDocType ===
				'document'
					? 'border-primary bg-primary/10'
					: 'border-light/20'}"
				onclick={() => (newDocType = "document")}
			>
				<span
					class="material-symbols-rounded text-h4 mr-1"
					style="font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
					>description</span
				>
				{m.files_type_document()}
			</button>
			<button
				type="button"
				class="flex-1 py-2 px-4 rounded-lg border transition-colors {newDocType ===
				'folder'
					? 'border-primary bg-primary/10'
					: 'border-light/20'}"
				onclick={() => (newDocType = "folder")}
			>
				<span
					class="material-symbols-rounded text-h4 mr-1"
					style="font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
					>folder</span
				>
				{m.files_type_folder()}
			</button>
			<button
				type="button"
				class="flex-1 py-2 px-4 rounded-lg border transition-colors {newDocType ===
				'kanban'
					? 'border-primary bg-primary/10'
					: 'border-light/20'}"
				onclick={() => (newDocType = "kanban")}
			>
				<span
					class="material-symbols-rounded text-h4 mr-1"
					style="font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
					>view_kanban</span
				>
				{m.files_type_kanban()}
			</button>
		</div>
		<Input
			label={m.files_name_label()}
			bind:value={newDocName}
			placeholder={newDocType === "folder"
				? m.files_folder_placeholder()
				: newDocType === "kanban"
					? m.files_kanban_placeholder()
					: m.files_doc_placeholder()}
		/>
		<div class="flex justify-end gap-2 pt-2">
			<Button variant="tertiary" onclick={() => (showCreateModal = false)}
				>{m.btn_cancel()}</Button
			>
			<Button onclick={handleCreate} disabled={!newDocName.trim()}
				>{m.btn_create()}</Button
			>
		</div>
	</div>
</Modal>

<!-- Context Menu -->
{#if contextMenu}
	<!-- svelte-ignore a11y_click_events_have_key_events -->
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="fixed inset-0 z-50" onclick={closeContextMenu}></div>
	<div
		class="fixed z-50 bg-night border border-light/10 rounded-xl shadow-2xl py-1 min-w-[200px]"
		style="left: {contextMenu.x}px; top: {contextMenu.y}px;"
	>
		<button
			type="button"
			class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-white hover:bg-dark transition-colors"
			onclick={contextRename}
		>
			<span
				class="material-symbols-rounded text-light"
				style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
				>edit</span
			>
			{m.files_context_rename()}
		</button>
		<button
			type="button"
			class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-white hover:bg-dark transition-colors"
			onclick={contextCopy}
		>
			<span
				class="material-symbols-rounded text-light"
				style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
				>content_copy</span
			>
			Make a copy
		</button>
		<div class="relative">
			<button
				type="button"
				class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-white hover:bg-dark transition-colors"
				onclick={contextOrganize}
			>
				<span
					class="material-symbols-rounded text-light"
					style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
					>drive_file_move</span
				>
				Organize
				<span
					class="material-symbols-rounded text-light/50 ml-auto"
					style="font-size: 16px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 16;"
					>chevron_right</span
				>
			</button>
			{#if showOrganizeMenu}
				<div
					class="absolute left-full top-0 ml-1 bg-night border border-light/10 rounded-xl shadow-2xl py-1 min-w-[180px] max-h-[240px] overflow-auto"
				>
					{#if contextMenu.doc.parent_id !== null}
						<button
							type="button"
							class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-white hover:bg-dark transition-colors"
							onclick={() => contextMoveToFolder(null)}
						>
							<span
								class="material-symbols-rounded text-light"
								style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
								>home</span
							>
							Home
						</button>
					{/if}
					{#each availableFolders as folder}
						{#if folder.id !== contextMenu.doc.parent_id}
							<button
								type="button"
								class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-white hover:bg-dark transition-colors"
								onclick={() => contextMoveToFolder(folder.id)}
							>
								<span
									class="material-symbols-rounded text-light"
									style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
									>folder</span
								>
								{folder.name}
							</button>
						{/if}
					{/each}
				</div>
			{/if}
		</div>
		<div class="border-t border-light/10 my-1"></div>
		<button
			type="button"
			class="w-full flex items-center gap-3 px-4 py-2.5 text-left text-body-md text-error hover:bg-error/10 transition-colors"
			onclick={contextDelete}
		>
			<span
				class="material-symbols-rounded"
				style="font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;"
				>delete</span
			>
			{m.files_context_delete()}
		</button>
	</div>
{/if}

<Modal
	isOpen={showEditModal}
	onClose={() => {
		showEditModal = false;
		editingDoc = null;
		newDocName = "";
	}}
	title={m.files_rename_title()}
>
	<div class="space-y-4">
		<Input
			label={m.files_name_label()}
			bind:value={newDocName}
			placeholder={m.files_name_label()}
		/>
		<div class="flex justify-end gap-2 pt-2">
			<Button
				variant="tertiary"
				onclick={() => {
					showEditModal = false;
					editingDoc = null;
					newDocName = "";
				}}>{m.btn_cancel()}</Button
			>
			<Button onclick={handleRename} disabled={!newDocName.trim()}
				>{m.btn_save()}</Button
			>
		</div>
	</div>
</Modal>
