<script lang="ts">
	import { getContext } from "svelte";
	import { Button, Modal, Input } from "$lib/components/ui";
	import { FileTree, Editor } from "$lib/components/documents";
	import { buildDocumentTree } from "$lib/api/documents";
	import type { Document } from "$lib/supabase/types";
	import type { SupabaseClient } from "@supabase/supabase-js";
	import type { Database } from "$lib/supabase/types";

	interface Props {
		data: {
			org: { id: string; name: string; slug: string };
			documents: Document[];
			user: { id: string } | null;
		};
	}

	let { data }: Props = $props();

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

	let documents = $state(data.documents);
	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">("document");
	let parentFolderId = $state<string | null>(null);
	let isEditing = $state(false);

	const documentTree = $derived(buildDocumentTree(documents));

	function handleSelect(doc: Document) {
		if (doc.type === "document") {
			selectedDoc = doc;
		}
	}

	function handleAdd(folderId: string | null) {
		parentFolderId = folderId;
		showCreateModal = true;
	}

	async function handleMove(docId: string, newParentId: string | null) {
		const { error } = await supabase
			.from("documents")
			.update({
				parent_id: newParentId,
				updated_at: new Date().toISOString(),
			})
			.eq("id", docId);

		if (!error) {
			documents = documents.map((d) =>
				d.id === docId ? { ...d, parent_id: newParentId } : d,
			);
		}
	}

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

		const { data: newDoc, error } = await supabase
			.from("documents")
			.insert({
				org_id: data.org.id,
				name: newDocName,
				type: newDocType,
				parent_id: parentFolderId,
				created_by: data.user.id,
				content:
					newDocType === "document"
						? { type: "doc", content: [] }
						: null,
			})
			.select()
			.single();

		if (!error && newDoc) {
			documents = [...documents, newDoc];
			if (newDocType === "document") {
				selectedDoc = newDoc;
			}
		}

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

	async function handleSave(content: unknown) {
		if (!selectedDoc) return;

		await supabase
			.from("documents")
			.update({ content, updated_at: new Date().toISOString() })
			.eq("id", selectedDoc.id);

		documents = documents.map((d) =>
			d.id === selectedDoc!.id ? { ...d, content } : d,
		);
	}

	function handleEdit(doc: Document) {
		editingDoc = doc;
		newDocName = doc.name;
		showEditModal = true;
	}

	async function handleRename() {
		if (!editingDoc || !newDocName.trim()) return;

		const { error } = await supabase
			.from("documents")
			.update({ name: newDocName, updated_at: new Date().toISOString() })
			.eq("id", editingDoc.id);

		if (!error) {
			documents = documents.map((d) =>
				d.id === editingDoc!.id ? { ...d, name: newDocName } : d,
			);
			if (selectedDoc?.id === editingDoc.id) {
				selectedDoc = { ...selectedDoc, name: newDocName };
			}
		}
		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;

		// If deleting a folder, delete all children first
		if (doc.type === "folder") {
			const childIds = documents
				.filter((d) => d.parent_id === doc.id)
				.map((d) => d.id);
			if (childIds.length > 0) {
				await supabase.from("documents").delete().in("id", childIds);
			}
		}

		const { error } = await supabase
			.from("documents")
			.delete()
			.eq("id", doc.id);

		if (!error) {
			documents = documents.filter(
				(d) => d.id !== doc.id && d.parent_id !== doc.id,
			);
			if (selectedDoc?.id === doc.id) {
				selectedDoc = null;
			}
		}
	}
</script>

<svelte:head>
	<title
		>{selectedDoc ? `${selectedDoc.name} - ` : ""}Documents - {data.org
			.name} | Root</title
	>
</svelte:head>

<div class="flex h-full">
	<aside class="w-72 border-r border-light/10 flex flex-col">
		<div
			class="p-4 border-b border-light/10 flex items-center justify-between"
		>
			<h2 class="font-semibold text-light">Documents</h2>
			<Button size="sm" onclick={() => (showCreateModal = true)}>
				<svg
					class="w-4 h-4"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
				>
					<line x1="12" y1="5" x2="12" y2="19" />
					<line x1="5" y1="12" x2="19" y2="12" />
				</svg>
			</Button>
		</div>

		<div class="flex-1 overflow-y-auto p-2">
			{#if documentTree.length === 0}
				<div class="text-center text-light/40 py-8 text-sm">
					<p>No documents yet</p>
					<p class="mt-1">Create your first document</p>
				</div>
			{:else}
				<FileTree
					items={documentTree}
					selectedId={selectedDoc?.id ?? null}
					onSelect={handleSelect}
					onAdd={handleAdd}
					onMove={handleMove}
					onEdit={handleEdit}
					onDelete={handleDelete}
				/>
			{/if}
		</div>
	</aside>

	<main class="flex-1 overflow-hidden flex flex-col">
		{#if selectedDoc}
			<div
				class="flex items-center justify-between p-4 border-b border-light/10"
			>
				<h2 class="text-lg font-semibold text-light">
					{selectedDoc.name}
				</h2>
				<button
					class="px-4 py-2 rounded-lg text-sm font-medium transition-colors {isEditing
						? 'bg-primary text-white'
						: 'bg-light/10 text-light hover:bg-light/20'}"
					onclick={() => (isEditing = !isEditing)}
				>
					{isEditing ? "Preview" : "Edit"}
				</button>
			</div>
			<div class="flex-1 overflow-auto">
				<Editor
					document={selectedDoc}
					onSave={handleSave}
					editable={isEditing}
				/>
			</div>
		{:else}
			<div class="h-full flex items-center justify-center text-light/40">
				<div class="text-center">
					<svg
						class="w-16 h-16 mx-auto mb-4 opacity-50"
						viewBox="0 0 24 24"
						fill="none"
						stroke="currentColor"
						stroke-width="1.5"
					>
						<path
							d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
						/>
						<polyline points="14,2 14,8 20,8" />
					</svg>
					<p>Select a document to edit</p>
				</div>
			</div>
		{/if}
	</main>
</div>

<Modal
	isOpen={showCreateModal}
	onClose={() => (showCreateModal = false)}
	title="Create New"
>
	<div class="space-y-4">
		<div class="flex gap-2">
			<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")}
			>
				Document
			</button>
			<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")}
			>
				Folder
			</button>
		</div>

		<Input
			label="Name"
			bind:value={newDocName}
			placeholder={newDocType === "folder"
				? "Folder name"
				: "Document name"}
		/>

		<div class="flex justify-end gap-2 pt-2">
			<Button variant="ghost" onclick={() => (showCreateModal = false)}
				>Cancel</Button
			>
			<Button onclick={handleCreate} disabled={!newDocName.trim()}
				>Create</Button
			>
		</div>
	</div>
</Modal>

<Modal
	isOpen={showEditModal}
	onClose={() => {
		showEditModal = false;
		editingDoc = null;
		newDocName = "";
	}}
	title="Rename"
>
	<div class="space-y-4">
		<Input
			label="Name"
			bind:value={newDocName}
			placeholder="Enter new name"
		/>

		<div class="flex justify-end gap-2 pt-2">
			<Button
				variant="ghost"
				onclick={() => {
					showEditModal = false;
					editingDoc = null;
					newDocName = "";
				}}>Cancel</Button
			>
			<Button onclick={handleRename} disabled={!newDocName.trim()}
				>Save</Button
			>
		</div>
	</div>
</Modal>
