<script lang="ts">
	/**
	 * StoryboardTrait — Storyboard-panel med Flow Meter.
	 *
	 * Viser en varighetsindikator (Flow Meter) øverst basert på kort
	 * med status "tatt_opp" som tilhører samlingen. Kort med
	 * metadata.duration_seconds bidrar til total opptakstid.
	 *
	 * Konfigurasjon via trait-config:
	 *   { target_duration_minutes: 45 }
	 *
	 * Ref: docs/proposals/flow_meter.md, docs/proposals/storyboard.md
	 */
	import type { Node, Edge } from '$lib/realtime';
	import { edgeStore, nodeStore, nodeVisibility } from '$lib/realtime';
	import FlowMeter from './FlowMeter.svelte';

	interface Props {
		collection?: Node;
		config: Record<string, unknown>;
		userId?: string;
		accessToken?: string;
	}

	let { collection, config, userId, accessToken }: Props = $props();

	/** Målvarighet fra trait-config, default 45 minutter */
	const targetMinutes = $derived(
		typeof config.target_duration_minutes === 'number'
			? config.target_duration_minutes
			: 45
	);

	/** Alle kort som tilhører samlingen */
	interface CardData {
		node: Node;
		status: string;
		durationSeconds: number;
	}

	const cards = $derived.by((): CardData[] => {
		if (!collection?.id) return [];

		const result: CardData[] = [];

		for (const edge of edgeStore.byTarget(collection.id)) {
			if (edge.edgeType !== 'belongs_to') continue;

			const node = nodeStore.get(edge.sourceId);
			if (!node || nodeVisibility(node, userId) === 'hidden') continue;

			let status = 'klar';
			for (const e of edgeStore.bySource(node.id)) {
				if (e.edgeType === 'status' && e.targetId === collection.id) {
					try {
						const meta = JSON.parse(e.metadata ?? '{}');
						if (meta.value) status = meta.value;
					} catch { /* ignore */ }
					break;
				}
			}

			let durationSeconds = 0;
			try {
				const meta = JSON.parse(node.metadata ?? '{}');
				if (typeof meta.duration_seconds === 'number') {
					durationSeconds = meta.duration_seconds;
				}
			} catch { /* ignore */ }

			result.push({ node, status, durationSeconds });
		}

		return result;
	});

	const cardsByStatus = $derived.by(() => {
		const grouped: Record<string, CardData[]> = {
			klar: [],
			tatt_opp: [],
			droppet: [],
		};
		for (const card of cards) {
			const key = grouped[card.status] ? card.status : 'klar';
			grouped[key].push(card);
		}
		return grouped;
	});

	/** Summert opptakstid for "Tatt opp"-kort, i minutter */
	const recordedMinutes = $derived(
		(cardsByStatus.tatt_opp ?? []).reduce((sum, c) => sum + c.durationSeconds, 0) / 60
	);

	const statusLabels: Record<string, string> = {
		klar: 'Klar',
		tatt_opp: 'Tatt opp',
		droppet: 'Droppet',
	};

	const statusIcons: Record<string, string> = {
		klar: '',
		tatt_opp: '',
		droppet: '',
	};
</script>

<div class="storyboard-trait">
	<!-- Flow Meter — varighetsindikator -->
	<FlowMeter {targetMinutes} {recordedMinutes} />

	<!-- Kortliste gruppert etter status -->
	<div class="storyboard-cards">
		{#each ['tatt_opp', 'klar', 'droppet'] as status (status)}
			{@const group = cardsByStatus[status] ?? []}
			{#if group.length > 0}
				<div class="storyboard-group">
					<div class="storyboard-group-header">
						<span class="storyboard-status-icon">{statusIcons[status]}</span>
						<span class="storyboard-status-label">{statusLabels[status]}</span>
						<span class="storyboard-status-count">{group.length}</span>
					</div>
					{#each group as card (card.node.id)}
						<div class="storyboard-card storyboard-card--{status}">
							<span class="storyboard-card-title">{card.node.title || 'Uten tittel'}</span>
							{#if card.durationSeconds > 0}
								<span class="storyboard-card-duration">
									{Math.floor(card.durationSeconds / 60)}:{(card.durationSeconds % 60).toString().padStart(2, '0')}
								</span>
							{/if}
						</div>
					{/each}
				</div>
			{/if}
		{/each}

		{#if cards.length === 0}
			<div class="storyboard-empty">
				<p>Ingen kort ennå.</p>
				<p class="storyboard-empty-hint">
					Legg til kort med status for å se episodeprogresjonen i Flow Meter.
				</p>
			</div>
		{/if}
	</div>
</div>

<style>
	.storyboard-trait {
		display: flex;
		flex-direction: column;
		height: 100%;
		min-height: 0;
		overflow: hidden;
	}

	/* ================================================================= */
	/* Card list                                                          */
	/* ================================================================= */
	.storyboard-cards {
		flex: 1;
		overflow-y: auto;
		padding: 0 8px 8px;
		display: flex;
		flex-direction: column;
		gap: 8px;
	}

	.storyboard-group {
		display: flex;
		flex-direction: column;
		gap: 3px;
	}

	.storyboard-group-header {
		display: flex;
		align-items: center;
		gap: 4px;
		padding: 4px 6px;
		font-size: 11px;
		color: #8a8a96;
	}

	.storyboard-status-icon {
		font-size: 12px;
	}

	.storyboard-status-label {
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: 0.03em;
		font-size: 10px;
	}

	.storyboard-status-count {
		margin-left: auto;
		font-size: 10px;
		color: #5a5a66;
		background: rgba(255, 255, 255, 0.06);
		border-radius: 9999px;
		padding: 0 5px;
		line-height: 16px;
	}

	/* ================================================================= */
	/* Card                                                               */
	/* ================================================================= */
	.storyboard-card {
		display: flex;
		align-items: center;
		gap: 6px;
		padding: 6px 8px;
		background: rgba(255, 255, 255, 0.04);
		border: 1px solid rgba(255, 255, 255, 0.06);
		border-radius: 6px;
		border-left: 3px solid transparent;
		transition: background 0.1s;
	}

	.storyboard-card:hover {
		background: rgba(255, 255, 255, 0.07);
	}

	.storyboard-card--klar {
		border-left-color: rgba(255, 255, 255, 0.2);
	}

	.storyboard-card--tatt_opp {
		border-left-color: #22c55e;
	}

	.storyboard-card--droppet {
		border-left-color: #ef4444;
		opacity: 0.5;
	}

	.storyboard-card-title {
		flex: 1;
		font-size: 12px;
		color: #c4c4cc;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.storyboard-card-duration {
		font-size: 10px;
		font-variant-numeric: tabular-nums;
		color: #8a8a96;
		flex-shrink: 0;
	}

	/* ================================================================= */
	/* Empty state                                                        */
	/* ================================================================= */
	.storyboard-empty {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		flex: 1;
		padding: 24px;
		text-align: center;
		color: #5a5a66;
		font-size: 13px;
		gap: 4px;
	}

	.storyboard-empty-hint {
		font-size: 11px;
		color: #4a4a54;
	}

	/* ================================================================= */
	/* Responsive                                                         */
	/* ================================================================= */
	@container (max-width: 300px) {
		.storyboard-card {
			padding: 4px 6px;
		}

		.storyboard-card-title {
			font-size: 11px;
		}
	}

	@media (max-width: 480px) {
		.storyboard-cards {
			padding: 0 6px 6px;
		}
	}
</style>
