<script lang="ts">
	import { Card, Badge, Spinner, Button, Modal, FormField } from '$lib/components';
	import { createTask, updateTask, deleteTask, addTaskComment } from '$lib/api/admin';
	import { toast } from '$lib/stores/toast.svelte';
	import { data } from '$lib/stores/data.svelte';
	import type { Task, TaskComment } from '$lib/types';
	import { Plus, Trash2, MessageSquare, Archive, ArchiveX, Copy, Check } from "lucide-svelte";
	import { navbarExtra } from '$lib/stores/navbar-extra.svelte';
	import { onDestroy } from 'svelte';

	// Columns
	const columns: { key: Task['status']; label: string }[] = [
		{ key: 'backlog', label: 'Backlog' },
		{ key: 'todo', label: 'To Do' },
		{ key: 'in_progress', label: 'In Progress' },
		{ key: 'in_review', label: 'In Review' },
		{ key: 'done', label: 'Done' },
	];

	// Create modal
	let showCreate = $state(false);
	let createForm = $state({
		title: '', description: '', status: 'todo' as Task['status'],
		priority: 'normal' as Task['priority'], assigned_to: '', labels: ''
	});
	let creating = $state(false);

	// Detail/edit modal
	let selectedTask = $state<Task | null>(null);
	let editForm = $state({
		title: '', description: '', status: 'todo' as Task['status'],
		priority: 'normal' as Task['priority'], assigned_to: '', labels: ''
	});
	let saving = $state(false);
	let newComment = $state('');
	let addingComment = $state(false);
	let idCopied = $state(false);

	// Delete
	let deleteTarget = $state<Task | null>(null);
	let deleting = $state(false);

	// Drag and drop
	let draggingTaskId = $state<string | null>(null);
	let dragOverColumn = $state<Task['status'] | null>(null);

	// Archive all
	let showArchiveAll = $state(false);
	let archivingAll = $state(false);

	async function handleArchiveAll() {
		archivingAll = true;
		try {
			const done = tasksByStatus('done');
			await Promise.all(done.map(t => updateTask(t.id, { status: 'archived' as any })));
			done.forEach(t => data.upsertTask({ ...t, status: 'archived' as any }));
			showArchiveAll = false;
			toast.success(`Archived ${done.length} task${done.length === 1 ? '' : 's'}`);
		} catch (e: any) {
			toast.error(e.message || 'Failed to archive tasks');
		} finally {
			archivingAll = false;
		}
	}

	// Mobile column collapse
	let collapsedColumns = $state<Set<Task['status']>>(new Set(['backlog']));
	function toggleColumn(key: Task['status']) {
		const next = new Set(collapsedColumns);
		if (next.has(key)) next.delete(key); else next.add(key);
		collapsedColumns = next;
	}

	$effect(() => {
		navbarExtra.set(addTaskBtn);
		return () => navbarExtra.set(null);
	});
	onDestroy(() => navbarExtra.set(null));

	function tasksByStatus(status: Task['status']): Task[] {
		return data.tasks.filter(t => t.status === status);
	}

	function priorityColor(p: Task['priority']): 'rose' | 'amber' | 'accent' | 'dim' {
		if (p === 'urgent') return 'rose';
		if (p === 'high') return 'amber';
		if (p === 'normal') return 'accent';
		return 'dim';
	}

	async function handleCreate() {
		creating = true;
		try {
			await createTask({
				title: createForm.title,
				description: createForm.description || undefined,
				status: createForm.status,
				priority: createForm.priority,
				assigned_to: createForm.assigned_to || undefined,
				labels: createForm.labels ? createForm.labels.split(',').map(l => l.trim()).filter(Boolean) : [],
			});
			await data.refetchTasks();
			toast.success('Task created');
			showCreate = false;
			resetCreateForm();
		} catch (e: any) {
			toast.error(e.message || 'Failed to create task');
		} finally {
			creating = false;
		}
	}

	function openDetail(task: Task) {
		selectedTask = task;
		editForm = {
			title: task.title,
			description: task.description || '',
			status: task.status,
			priority: task.priority,
			assigned_to: task.assigned_to || '',
			labels: task.labels.join(', '),
		};
		newComment = '';
	}

	async function handleSave() {
		if (!selectedTask) return;
		saving = true;
		try {
			await updateTask(selectedTask.id, {
				title: editForm.title,
				description: editForm.description || undefined,
				status: editForm.status,
				priority: editForm.priority,
				assigned_to: editForm.assigned_to || undefined,
				labels: editForm.labels ? editForm.labels.split(',').map(l => l.trim()).filter(Boolean) : [],
			});
			await data.refetchTasks();
			toast.success('Task updated');
			selectedTask = null;
		} catch (e: any) {
			toast.error(e.message || 'Failed to update task');
		} finally {
			saving = false;
		}
	}

	async function handleAddComment() {
		if (!selectedTask || !newComment.trim()) return;
		addingComment = true;
		try {
			const updated = await addTaskComment(selectedTask.id, { content: newComment.trim() });
			selectedTask = updated;
			data.upsertTask(updated);
			newComment = '';
		} catch (e: any) {
			toast.error(e.message || 'Failed to add comment');
		} finally {
			addingComment = false;
		}
	}

	function copyId() {
		if (!selectedTask) return;
		navigator.clipboard.writeText(selectedTask.id);
		idCopied = true;
		setTimeout(() => idCopied = false, 2000);
	}

	async function handleDelete() {
		if (!deleteTarget) return;
		deleting = true;
		try {
			await deleteTask(deleteTarget.id);
			await data.refetchTasks();
			toast.success('Task deleted');
			deleteTarget = null;
			selectedTask = null;
		} catch (e: any) {
			toast.error(e.message || 'Failed to delete task');
		} finally {
			deleting = false;
		}
	}

	function resetCreateForm() {
		createForm = { title: '', description: '', status: 'todo', priority: 'normal', assigned_to: '', labels: '' };
	}

	function formatDate(d: string): string {
		return new Date(d).toLocaleDateString();
	}

	async function handleDrop(status: Task['status']) {
		if (!draggingTaskId) return;
		const task = data.tasks.find(t => t.id === draggingTaskId);
		if (!task || task.status === status) { draggingTaskId = null; dragOverColumn = null; return; }
		const prev = task.status;
		data.upsertTask({ ...task, status });
		draggingTaskId = null;
		dragOverColumn = null;
		try {
			await updateTask(task.id, { status });
		} catch (e: any) {
			data.upsertTask({ ...task, status: prev });
			toast.error(e.message || 'Failed to move task');
		}
	}

	async function handleArchive(task: Task, e: MouseEvent) {
		e.stopPropagation();
		try {
			await updateTask(task.id, { status: 'archived' as any });
			data.upsertTask({ ...task, status: 'archived' as any });
		} catch (e: any) {
			toast.error(e.message || 'Failed to archive task');
		}
	}
</script>

{#snippet addTaskBtn()}
	<Button variant="primary" size="sm" onclick={() => { resetCreateForm(); showCreate = true; }}>
		<Plus size={14} />
		Add Task
	</Button>
{/snippet}

<div class="page">

	{#if !data.initialLoaded}
		<div class="center"><Spinner /></div>
	{:else}
		<div class="board">
			{#each columns as col}
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div
					class="column"
					class:drag-over={dragOverColumn === col.key}
					class:collapsed={collapsedColumns.has(col.key)}
					ondragover={(e) => { e.preventDefault(); dragOverColumn = col.key; }}
					ondragleave={() => { if (dragOverColumn === col.key) dragOverColumn = null; }}
					ondrop={() => handleDrop(col.key)}
				>
					<!-- svelte-ignore a11y_click_events_have_key_events -->
					<div class="column-header" onclick={() => toggleColumn(col.key)}>
						<span class="column-title">{col.label}</span>
						<div class="column-header-right">
							<span class="column-count">{tasksByStatus(col.key).length}</span>
							{#if col.key === 'done' && tasksByStatus('done').length > 0}
								<!-- svelte-ignore a11y_click_events_have_key_events -->
								<button
									class="archive-all-btn"
									title="Archive all done tasks"
									onclick={(e) => { e.stopPropagation(); showArchiveAll = true; }}
								><ArchiveX size={13} /></button>
							{/if}
							<span class="column-chevron">{collapsedColumns.has(col.key) ? '▶' : '▼'}</span>
						</div>
					</div>
					<div class="column-cards">
						{#each tasksByStatus(col.key) as task (task.id)}
							<!-- svelte-ignore a11y_click_events_have_key_events -->
							<!-- svelte-ignore a11y_no_static_element_interactions -->
							<div
								class="task-card"
								class:dragging={draggingTaskId === task.id}
								draggable={true}
								ondragstart={() => { draggingTaskId = task.id; }}
								ondragend={() => { draggingTaskId = null; dragOverColumn = null; }}
								onclick={() => openDetail(task)}
							>
								<div class="task-title">{task.title}</div>
								<div class="task-meta">
									<Badge color={priorityColor(task.priority)}>{task.priority}</Badge>
									{#if task.assigned_to}
										<span class="assigned">{task.assigned_to}</span>
									{/if}
									{#if col.key === 'done'}
										<!-- svelte-ignore a11y_click_events_have_key_events -->
										<button class="archive-btn" onclick={(e) => handleArchive(task, e)} title="Archive">
											<Archive size={12} />
										</button>
									{/if}
								</div>
								{#if task.labels.length > 0}
									<div class="task-labels">
										{#each task.labels as label}
											<span class="label-tag">{label}</span>
										{/each}
									</div>
								{/if}
								{#if task.comments.length > 0}
									<div class="task-comments-count">
										<MessageSquare size={12} />
										<span>{task.comments.length}</span>
									</div>
								{/if}
							</div>
						{/each}
					</div>
				</div>
			{/each}
		</div>
	{/if}
</div>

<!-- Create Task Modal -->
<Modal open={showCreate} title="New Task" onclose={() => showCreate = false}>
	<div class="form-stack">
		<FormField label="Title">
			<input type="text" bind:value={createForm.title} placeholder="Task title" />
		</FormField>
		<FormField label="Description">
			<textarea bind:value={createForm.description} placeholder="Optional description"></textarea>
		</FormField>
		<div class="form-row">
			<FormField label="Status">
				<select bind:value={createForm.status}>
					{#each columns as col}
						<option value={col.key}>{col.label}</option>
					{/each}
				</select>
			</FormField>
			<FormField label="Priority">
				<select bind:value={createForm.priority}>
					<option value="low">Low</option>
					<option value="normal">Normal</option>
					<option value="high">High</option>
					<option value="urgent">Urgent</option>
				</select>
			</FormField>
		</div>
		<FormField label="Assigned To">
			<input type="text" bind:value={createForm.assigned_to} placeholder="Optional" />
		</FormField>
		<FormField label="Labels" hint="Comma-separated">
			<input type="text" bind:value={createForm.labels} placeholder="bug, frontend" />
		</FormField>
	</div>
	{#snippet footer()}
		<Button variant="secondary" onclick={() => showCreate = false}>Cancel</Button>
		<Button variant="primary" loading={creating} onclick={handleCreate} disabled={!createForm.title.trim()}>Create</Button>
	{/snippet}
</Modal>

<!-- Detail/Edit Modal -->
<Modal open={selectedTask !== null} title="Task Detail" width="640px" onclose={() => selectedTask = null}>
	{#if selectedTask}
		<div class="form-stack">
			<div class="id-row">
				<span class="id-label">Task ID</span>
				<span class="id-value">{selectedTask.id}</span>
				<button class="copy-btn" onclick={copyId} title="Copy task ID">
					{#if idCopied}<Check size={13} />{:else}<Copy size={13} />{/if}
				</button>
			</div>
			<FormField label="Title">
				<input type="text" bind:value={editForm.title} />
			</FormField>
			<FormField label="Description">
				<textarea bind:value={editForm.description}></textarea>
			</FormField>
			<div class="form-row">
				<FormField label="Status">
					<select bind:value={editForm.status}>
						{#each columns as col}
							<option value={col.key}>{col.label}</option>
						{/each}
					</select>
				</FormField>
				<FormField label="Priority">
					<select bind:value={editForm.priority}>
						<option value="low">Low</option>
						<option value="normal">Normal</option>
						<option value="high">High</option>
						<option value="urgent">Urgent</option>
					</select>
				</FormField>
			</div>
			<FormField label="Assigned To">
				<input type="text" bind:value={editForm.assigned_to} />
			</FormField>
			<FormField label="Labels" hint="Comma-separated">
				<input type="text" bind:value={editForm.labels} />
			</FormField>

			<!-- Comments -->
			<div class="comments-section">
				<h4 class="comments-title">Comments ({selectedTask.comments.length})</h4>
				{#if selectedTask.comments.length > 0}
					<div class="comments-list">
						{#each selectedTask.comments as comment (comment.id)}
							<div class="comment">
								<div class="comment-header">
									<span class="comment-author">{comment.author}</span>
									<span class="comment-date">{formatDate(comment.created_at)}</span>
								</div>
								<p class="comment-content">{comment.content}</p>
							</div>
						{/each}
					</div>
				{/if}
				<div class="comment-input">
					<textarea bind:value={newComment} placeholder="Add a comment..." rows="2"></textarea>
					<Button size="sm" loading={addingComment} onclick={handleAddComment} disabled={!newComment.trim()}>
						Comment
					</Button>
				</div>
			</div>
		</div>
	{/if}
	{#snippet footer()}
		<Button variant="danger" onclick={() => { deleteTarget = selectedTask; }}>
			<Trash2 size={13} />
			Delete
		</Button>
		<div style="flex:1"></div>
		<Button variant="secondary" onclick={() => selectedTask = null}>Cancel</Button>
		<Button variant="primary" loading={saving} onclick={handleSave}>Save</Button>
	{/snippet}
</Modal>

<!-- Archive All Confirmation -->
<Modal open={showArchiveAll} title="Archive All Done Tasks" onclose={() => showArchiveAll = false}>
	<p class="confirm-text">Archive all <strong>{tasksByStatus('done').length}</strong> task{tasksByStatus('done').length === 1 ? '' : 's'} in the Done column?</p>
	{#snippet footer()}
		<Button variant="secondary" onclick={() => showArchiveAll = false}>Cancel</Button>
		<Button variant="primary" loading={archivingAll} onclick={handleArchiveAll}>
			<ArchiveX size={13} />
			Archive All
		</Button>
	{/snippet}
</Modal>

<!-- Delete Confirmation -->
<Modal open={deleteTarget !== null} title="Delete Task" onclose={() => deleteTarget = null}>
	<p class="confirm-text">Are you sure you want to delete <strong>"{deleteTarget?.title}"</strong>?</p>
	{#snippet footer()}
		<Button variant="secondary" onclick={() => deleteTarget = null}>Cancel</Button>
		<Button variant="danger" loading={deleting} onclick={handleDelete}>Delete</Button>
	{/snippet}
</Modal>

<style>
	.page {
		display: flex;
		flex-direction: column;
		gap: 20px;
	}
	.page-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
	}
	.page-title {
		display: flex;
		align-items: center;
		gap: 10px;
		color: var(--text-bright);
	}
	.page-title h1 {
		font-size: var(--font-size-xl);
		font-weight: 700;
	}
	.center {
		display: flex;
		justify-content: center;
		padding: 60px 0;
	}
	.board {
		display: grid;
		grid-template-columns: repeat(5, 1fr);
		gap: 12px;
		min-height: 400px;
		align-items: start;
	}
	.column {
		background: var(--surface-0);
		border: 1px solid var(--border-subtle);
		border-radius: var(--radius-lg);
		display: flex;
		flex-direction: column;
		min-height: 0;
	}
	.column-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 10px 12px;
		border-bottom: 1px solid var(--border-subtle);
		cursor: default;
	}
	.column-header-right {
		display: flex;
		align-items: center;
		gap: 6px;
	}
	.column-chevron {
		display: none;
		font-size: 9px;
		color: var(--text-muted);
	}
	.column-title {
		font-size: var(--font-size-xs);
		font-weight: 600;
		color: var(--text-dim);
		text-transform: uppercase;
		letter-spacing: 0.05em;
	}
	.column-count {
		font-size: var(--font-size-xs);
		font-family: var(--font-mono);
		color: var(--text-muted);
		background: var(--surface-2);
		padding: 1px 6px;
		border-radius: 99px;
	}
	.column-cards {
		padding: 8px;
		display: flex;
		flex-direction: column;
		gap: 8px;
		overflow-y: auto;
		flex: 1;
	}
	@media (max-width: 1100px) {
		.board {
			grid-template-columns: 1fr;
			min-height: 0;
		}
		.column-header {
			cursor: pointer;
			user-select: none;
		}
		.column-chevron {
			display: inline;
		}
		.column.collapsed .column-cards {
			display: none;
		}
		.column.collapsed .column-header {
			border-bottom: none;
		}
	}

	@media (max-width: 768px) {
		.board {
			gap: 8px;
		}
		.form-row {
			grid-template-columns: 1fr;
		}
	}
	.task-card {
		background: var(--surface-1);
		border: 1px solid var(--border);
		border-radius: var(--radius);
		padding: 10px 12px;
		cursor: pointer;
		transition: all var(--duration) var(--ease);
		display: flex;
		flex-direction: column;
		gap: 6px;
	}
	.task-card:hover {
		border-color: var(--border-strong);
		background: var(--surface-2);
	}
	.task-card.dragging {
		opacity: 0.4;
	}
	.column.drag-over {
		background: var(--surface-1);
		border-color: var(--accent);
	}
	.column.drag-over .column-cards {
		background: color-mix(in srgb, var(--accent) 5%, transparent);
		border-radius: 0 0 var(--radius-lg) var(--radius-lg);
	}
	.archive-all-btn {
		background: none;
		border: none;
		color: var(--text-muted);
		cursor: pointer;
		padding: 2px;
		border-radius: var(--radius-sm);
		display: flex;
		align-items: center;
		transition: color var(--duration) var(--ease);
	}
	.archive-all-btn:hover {
		color: var(--amber);
	}
	.archive-btn {
		margin-left: auto;
		background: none;
		border: none;
		color: var(--text-muted);
		cursor: pointer;
		padding: 2px;
		border-radius: var(--radius-sm);
		display: flex;
		align-items: center;
		transition: color var(--duration) var(--ease);
	}
	.archive-btn:hover {
		color: var(--amber);
	}
	.task-title {
		font-size: var(--font-size-sm);
		font-weight: 500;
		color: var(--text-bright);
		line-height: 1.3;
	}
	.task-meta {
		display: flex;
		align-items: center;
		gap: 6px;
	}
	.assigned {
		font-size: var(--font-size-xs);
		color: var(--text-dim);
		font-family: var(--font-mono);
	}
	.task-labels {
		display: flex;
		flex-wrap: wrap;
		gap: 4px;
	}
	.label-tag {
		font-size: 10px;
		padding: 1px 6px;
		background: var(--surface-3);
		color: var(--text-dim);
		border-radius: 99px;
		font-family: var(--font-mono);
	}
	.task-comments-count {
		display: flex;
		align-items: center;
		gap: 4px;
		font-size: var(--font-size-xs);
		color: var(--text-muted);
	}
	.form-stack {
		display: flex;
		flex-direction: column;
		gap: 14px;
	}
	.id-row {
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 6px 10px;
		background: var(--bg-subtle);
		border: 1px solid var(--border-subtle);
		border-radius: 6px;
	}
	.id-label {
		font-size: 11px;
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		color: var(--text-muted);
		white-space: nowrap;
	}
	.id-value {
		font-family: var(--font-mono, monospace);
		font-size: 12px;
		color: var(--text-subtle);
		flex: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.copy-btn {
		background: none;
		border: none;
		cursor: pointer;
		padding: 2px 4px;
		color: var(--text-muted);
		border-radius: 4px;
		display: flex;
		align-items: center;
		transition: color 0.15s, background 0.15s;
	}
	.copy-btn:hover {
		color: var(--text);
		background: var(--bg-hover);
	}
	.form-row {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 12px;
	}
	.confirm-text {
		color: var(--text);
		line-height: 1.5;
	}
	.comments-section {
		border-top: 1px solid var(--border-subtle);
		padding-top: 14px;
	}
	.comments-title {
		font-size: var(--font-size-sm);
		font-weight: 600;
		color: var(--text-dim);
		margin-bottom: 10px;
	}
	.comments-list {
		display: flex;
		flex-direction: column;
		gap: 8px;
		margin-bottom: 12px;
		max-height: 200px;
		overflow-y: auto;
	}
	.comment {
		background: var(--surface-0);
		border: 1px solid var(--border-subtle);
		border-radius: var(--radius);
		padding: 8px 10px;
	}
	.comment-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 4px;
	}
	.comment-author {
		font-size: var(--font-size-xs);
		font-weight: 600;
		color: var(--text);
	}
	.comment-date {
		font-size: var(--font-size-xs);
		color: var(--text-muted);
	}
	.comment-content {
		font-size: var(--font-size-sm);
		color: var(--text-dim);
		line-height: 1.4;
	}
	.comment-input {
		display: flex;
		flex-direction: column;
		gap: 6px;
		align-items: flex-end;
	}
	.comment-input textarea {
		width: 100%;
		background: var(--surface-0);
		border: 1px solid var(--border);
		border-radius: var(--radius);
		padding: 7px 10px;
		color: var(--text);
		font-size: var(--font-size-sm);
		resize: vertical;
	}
	.comment-input textarea:focus {
		outline: none;
		border-color: var(--border-focus);
	}
</style>
