<script lang="ts">
	import { getContext } from "svelte";
	import { Button, Card, Modal, Input } from "$lib/components/ui";
	import { KanbanBoard, CardDetailModal } from "$lib/components/kanban";
	import {
		fetchBoardWithColumns,
		createBoard,
		moveCard,
	} from "$lib/api/kanban";
	import type {
		KanbanBoard as KanbanBoardType,
		KanbanCard,
	} from "$lib/supabase/types";
	import type { BoardWithColumns } from "$lib/api/kanban";
	import type { SupabaseClient } from "@supabase/supabase-js";
	import type { Database } from "$lib/supabase/types";

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

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

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

	let boards = $state(data.boards);
	let selectedBoard = $state<BoardWithColumns | null>(null);
	let showCreateBoardModal = $state(false);
	let showEditBoardModal = $state(false);
	let showCardDetailModal = $state(false);
	let selectedCard = $state<KanbanCard | null>(null);
	let newBoardName = $state("");
	let editBoardName = $state("");
	let targetColumnId = $state<string | null>(null);
	let cardModalMode = $state<"edit" | "create">("edit");

	async function loadBoard(boardId: string) {
		selectedBoard = await fetchBoardWithColumns(supabase, boardId);
	}

	async function handleCreateBoard() {
		if (!newBoardName.trim()) return;

		const newBoard = await createBoard(supabase, data.org.id, newBoardName);
		boards = [...boards, newBoard];
		await loadBoard(newBoard.id);

		showCreateBoardModal = false;
		newBoardName = "";
	}

	let editingBoardId = $state<string | null>(null);

	function openEditBoardModal(board: KanbanBoardType) {
		editingBoardId = board.id;
		editBoardName = board.name;
		showEditBoardModal = true;
	}

	async function handleEditBoard() {
		if (!editingBoardId || !editBoardName.trim()) return;

		const { error } = await supabase
			.from("kanban_boards")
			.update({ name: editBoardName })
			.eq("id", editingBoardId);

		if (!error) {
			if (selectedBoard?.id === editingBoardId) {
				selectedBoard = { ...selectedBoard, name: editBoardName };
			}
			boards = boards.map((b) =>
				b.id === editingBoardId ? { ...b, name: editBoardName } : b,
			);
		}
		showEditBoardModal = false;
		editingBoardId = null;
	}

	async function handleDeleteBoard(e: MouseEvent, board: KanbanBoardType) {
		e.stopPropagation();
		if (!confirm(`Delete "${board.name}" and all its cards?`)) return;

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

		if (!error) {
			boards = boards.filter((b) => b.id !== board.id);
			if (selectedBoard?.id === board.id) {
				selectedBoard = null;
			}
		}
	}

	async function handleAddCard(columnId: string) {
		targetColumnId = columnId;
		selectedCard = null;
		cardModalMode = "create";
		showCardDetailModal = true;
	}

	function handleCardCreated(newCard: KanbanCard) {
		if (!selectedBoard) return;
		selectedBoard = {
			...selectedBoard,
			columns: selectedBoard.columns.map((col) =>
				col.id === newCard.column_id
					? { ...col, cards: [...col.cards, newCard] }
					: col,
			),
		};
		targetColumnId = null;
	}

	async function handleCardMove(
		cardId: string,
		toColumnId: string,
		toPosition: number,
	) {
		if (!selectedBoard) return;

		// Optimistic UI update - move card immediately
		const fromColumn = selectedBoard.columns.find((c) =>
			c.cards.some((card) => card.id === cardId),
		);
		const toColumn = selectedBoard.columns.find((c) => c.id === toColumnId);

		if (!fromColumn || !toColumn) return;

		const cardIndex = fromColumn.cards.findIndex((c) => c.id === cardId);
		if (cardIndex === -1) return;

		const [movedCard] = fromColumn.cards.splice(cardIndex, 1);
		movedCard.column_id = toColumnId;
		toColumn.cards.splice(toPosition, 0, movedCard);

		// Trigger reactivity
		selectedBoard = { ...selectedBoard };

		// Persist to database in background
		moveCard(supabase, cardId, toColumnId, toPosition).catch((err) => {
			console.error("Failed to persist card move:", err);
			// Reload to sync state on error
			loadBoard(selectedBoard!.id);
		});
	}

	function handleCardClick(card: KanbanCard) {
		selectedCard = card;
		cardModalMode = "edit";
		showCardDetailModal = true;
	}

	function handleCardUpdate(updatedCard: KanbanCard) {
		if (!selectedBoard) return;
		selectedBoard = {
			...selectedBoard,
			columns: selectedBoard.columns.map((col) => ({
				...col,
				cards: col.cards.map((c) =>
					c.id === updatedCard.id ? updatedCard : c,
				),
			})),
		};
		selectedCard = updatedCard;
	}

	async function handleCardDelete(cardId: string) {
		if (!selectedBoard) return;
		await loadBoard(selectedBoard.id);
	}
</script>

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

<div class="flex h-full">
	<aside class="w-64 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">Boards</h2>
			<Button size="sm" onclick={() => (showCreateBoardModal = 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 space-y-1">
			{#if boards.length === 0}
				<div class="text-center text-light/40 py-8 text-sm">
					<p>No boards yet</p>
				</div>
			{:else}
				{#each boards as board}
					<div
						class="group flex items-center gap-1 px-3 py-2 rounded-lg text-sm transition-colors cursor-pointer {selectedBoard?.id ===
						board.id
							? 'bg-primary text-white'
							: 'text-light/70 hover:bg-light/5'}"
						onclick={() => loadBoard(board.id)}
						role="button"
						tabindex="0"
					>
						<span class="flex-1 truncate">{board.name}</span>
						<div
							class="opacity-0 group-hover:opacity-100 flex items-center gap-0.5 transition-opacity"
						>
							<button
								class="p-1 rounded hover:bg-light/20"
								onclick={(e) => {
									e.stopPropagation();
									openEditBoardModal(board);
								}}
								title="Rename"
							>
								<svg
									class="w-3.5 h-3.5"
									viewBox="0 0 24 24"
									fill="none"
									stroke="currentColor"
									stroke-width="2"
								>
									<path
										d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
									/>
									<path
										d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
									/>
								</svg>
							</button>
							<button
								class="p-1 rounded hover:bg-error/20 hover:text-error"
								onclick={(e) => handleDeleteBoard(e, board)}
								title="Delete"
							>
								<svg
									class="w-3.5 h-3.5"
									viewBox="0 0 24 24"
									fill="none"
									stroke="currentColor"
									stroke-width="2"
								>
									<polyline points="3,6 5,6 21,6" />
									<path
										d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
									/>
								</svg>
							</button>
						</div>
					</div>
				{/each}
			{/if}
		</div>
	</aside>

	<main class="flex-1 overflow-hidden p-6">
		{#if selectedBoard}
			<header class="mb-6">
				<h1 class="text-2xl font-bold text-light">
					{selectedBoard.name}
				</h1>
			</header>

			<KanbanBoard
				columns={selectedBoard.columns}
				onCardClick={handleCardClick}
				onCardMove={handleCardMove}
				onAddCard={handleAddCard}
			/>
		{: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"
					>
						<rect x="3" y="3" width="18" height="18" rx="2" />
						<line x1="9" y1="3" x2="9" y2="21" />
						<line x1="15" y1="3" x2="15" y2="21" />
					</svg>
					<p>Select a board or create a new one</p>
				</div>
			</div>
		{/if}
	</main>
</div>

<Modal
	isOpen={showCreateBoardModal}
	onClose={() => (showCreateBoardModal = false)}
	title="Create Board"
>
	<div class="space-y-4">
		<Input
			label="Board Name"
			bind:value={newBoardName}
			placeholder="e.g. Sprint 1"
		/>
		<div class="flex justify-end gap-2">
			<Button
				variant="ghost"
				onclick={() => (showCreateBoardModal = false)}>Cancel</Button
			>
			<Button onclick={handleCreateBoard} disabled={!newBoardName.trim()}
				>Create</Button
			>
		</div>
	</div>
</Modal>

<Modal
	isOpen={showEditBoardModal}
	onClose={() => (showEditBoardModal = false)}
	title="Edit Board"
>
	<div class="space-y-4">
		<Input
			label="Board Name"
			bind:value={editBoardName}
			placeholder="Board name"
		/>
		<div class="flex justify-end gap-2">
			<Button variant="ghost" onclick={() => (showEditBoardModal = false)}
				>Cancel</Button
			>
			<Button onclick={handleEditBoard} disabled={!editBoardName.trim()}
				>Save</Button
			>
		</div>
	</div>
</Modal>

<CardDetailModal
	card={selectedCard}
	isOpen={showCardDetailModal}
	onClose={() => {
		showCardDetailModal = false;
		selectedCard = null;
		targetColumnId = null;
	}}
	onUpdate={handleCardUpdate}
	onDelete={handleCardDelete}
	mode={cardModalMode}
	columnId={targetColumnId ?? undefined}
	userId={data.user?.id}
	onCreate={handleCardCreated}
/>
