<script lang="ts">
	import { t } from 'svelte-i18n';
	import { dndzone } from 'svelte-dnd-action';
	import DraggableSection from '$lib/components/section/DraggableSection.svelte';

	interface WidgetData {
		id: string;
		type: string;
		order: number;
		config: string;
		appId: string | null;
		sectionId: string;
		app: {
			id: string;
			name: string;
			url: string;
			icon: string | null;
			iconType: string;
			description: string | null;
			statuses: Array<{ status: string; responseTime: number | null }>;
		} | null;
	}

	interface SectionData {
		id: string;
		title: string;
		icon: string | null;
		order: number;
		isExpandedByDefault: boolean;
		widgets: WidgetData[];
	}

	interface Props {
		boardId: string;
		sections: SectionData[];
		apps: Array<{ id: string; name: string }>;
		addWidgetSectionId: string | null;
		onToggleAddWidget: (sectionId: string) => void;
		onDeleteSection: (sectionId: string) => void;
		onAddWidget: (sectionId: string, widgetData: string) => void;
		onDeleteWidget: (widgetId: string) => void;
	}

	let {
		boardId,
		sections: initialSections,
		apps,
		addWidgetSectionId,
		onToggleAddWidget,
		onDeleteSection,
		onAddWidget,
		onDeleteWidget
	}: Props = $props();

	let sections = $state<SectionData[]>([...initialSections]);
	let dirty = $state(false);
	let errorMessage = $state('');

	// Keep local state in sync when parent data changes (skip during drag)
	$effect(() => {
		if (!dirty) {
			sections = [...initialSections];
		}
	});

	const flipDurationMs = 200;

	function handleConsider(e: CustomEvent<{ items: SectionData[] }>) {
		dirty = true;
		sections = e.detail.items;
	}

	async function handleFinalize(e: CustomEvent<{ items: SectionData[] }>) {
		dirty = true;
		sections = e.detail.items;
		const sectionIds = sections.map((s) => s.id);

		try {
			await fetch(`/api/boards/${boardId}/reorder`, {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ sectionIds })
			});
		} catch (err) {
			errorMessage = err instanceof Error ? err.message : 'Failed to persist section reorder';
		} finally {
			dirty = false;
		}
	}

	async function handleWidgetsUpdate(sectionId: string, widgets: WidgetData[]) {
		// Update local state
		dirty = true;
		sections = sections.map((s) => (s.id === sectionId ? { ...s, widgets } : s));

		const widgetIds = widgets.map((w) => w.id);

		try {
			await fetch(`/api/boards/${boardId}/sections/${sectionId}/reorder`, {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ widgetIds })
			});
		} catch (err) {
			errorMessage = err instanceof Error ? err.message : 'Failed to persist widget reorder';
		} finally {
			dirty = false;
		}
	}
</script>

{#if errorMessage}
	<p class="mb-2 text-sm text-destructive">{errorMessage}</p>
{/if}

{#if sections.length === 0}
	<div class="rounded-xl border border-border bg-card/50 p-8 text-center">
		<p class="text-muted-foreground">{$t('board.no_sections')}</p>
	</div>
{:else}
	<div
		use:dndzone={{ items: sections, flipDurationMs, dropTargetStyle: {} }}
		onconsider={handleConsider}
		onfinalize={handleFinalize}
		class="space-y-4"
	>
		{#each sections as section (section.id)}
			<div>
				<DraggableSection
					{section}
					{apps}
					onWidgetsUpdate={handleWidgetsUpdate}
					{addWidgetSectionId}
					{onToggleAddWidget}
					{onDeleteSection}
					{onAddWidget}
					{onDeleteWidget}
				/>
			</div>
		{/each}
	</div>
{/if}
