<script lang="ts">
	/**
	 * NoticeMosaic - Scroll-triggered mosaic of eviction notices
	 *
	 * Displays document images in a scattered "evidence board" layout,
	 * progressively revealing them as activeStep increases. Includes an
	 * animated text placard showing details for each notice.
	 */
	import { fade } from 'svelte/transition';
	import { onMount } from 'svelte';

	export interface Notice {
		image: string;
		alt: string;
		title: string;
		subtitle: string;
		excerpt: string;
	}

	interface Props {
		activeStep: number;
		notices: Notice[];
		backgroundColor?: string;
	}

	let { activeStep, notices, backgroundColor = '#1a1715' }: Props = $props();

	let viewportHeight = $state(0);
	let isMobile = $state(false);

	// Current notice index based on activeStep
	let currentNoticeIndex = $derived(Math.min(activeStep, notices.length - 1));

	// Pre-computed positions for each notice (deterministic based on index)
	function getPosition(index: number): [string, string, number] {
		const positions: [number, number, number][] = [
			[20, 15, -3],
			[50, 25, 2.5],
			[15, 45, -1.5],
			[55, 10, 3]
		];

		const pos = positions[index % positions.length];

		// Add slight randomization for organic feel (seeded by index)
		const seed = index * 7919;
		const jitterX = ((seed % 10) - 5) * 0.5;
		const jitterY = (((seed * 3) % 10) - 5) * 0.5;
		const jitterRot = (((seed * 7) % 10) - 5) * 0.2;

		return [
			`${pos[0] + jitterX}%`,
			`${pos[1] + jitterY}%`,
			pos[2] + jitterRot
		];
	}

	onMount(() => {
		viewportHeight = window.innerHeight;
		isMobile = window.innerWidth < 640;

		const handleResize = () => {
			viewportHeight = window.innerHeight;
			isMobile = window.innerWidth < 640;
		};

		window.addEventListener('resize', handleResize);
		return () => window.removeEventListener('resize', handleResize);
	});
</script>

<div class="notice-mosaic" style:background={backgroundColor}>
	<!-- Notice images -->
	{#each notices as notice, i}
		{@const pos = getPosition(i)}
		{#if i <= currentNoticeIndex}
			<div
				class="notice-image"
				class:mobile={isMobile}
				style:left={pos[0]}
				style:top={pos[1]}
				style:transform="rotate({pos[2]}deg)"
				in:fade={{ duration: 350 }}
			>
				<img src={notice.image} alt={notice.alt} loading="lazy" />
			</div>
		{/if}
	{/each}

	<!-- Text placard -->
	<div class="notice-placard" class:mobile={isMobile}>
		{#if notices[currentNoticeIndex]}
			{#key currentNoticeIndex}
				<div
					class="placard-content"
					in:fade={{ duration: 250, delay: 100 }}
					out:fade={{ duration: 150 }}
				>
					<p class="placard-title">{notices[currentNoticeIndex].title}</p>
					<p class="placard-subtitle">{notices[currentNoticeIndex].subtitle}</p>
					<p class="placard-excerpt">{notices[currentNoticeIndex].excerpt}</p>
				</div>
			{/key}
		{:else}
			<div class="placard-content placard-empty">
				<p class="placard-subtitle">Scroll to reveal eviction notices</p>
			</div>
		{/if}
	</div>
</div>

<style>
	.notice-mosaic {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		overflow: hidden;
	}

	/* Notice image cards - sized like photos on a desk */
	.notice-image {
		position: absolute;
		max-width: 25vw;
		box-shadow:
			0 2px 4px rgba(0, 0, 0, 0.1),
			0 4px 8px rgba(0, 0, 0, 0.1),
			0 8px 16px rgba(0, 0, 0, 0.15),
			0 16px 32px rgba(0, 0, 0, 0.2);
		border-radius: 2px;
		background: #f5f2eb;
		padding: 3px;
	}

	.notice-image.mobile {
		max-width: 50vw;
	}

	.notice-image img {
		display: block;
		width: 100%;
		height: auto;
		border-radius: 1px;
	}

	/* Text placard - museum card style with fixed height to prevent jumping */
	.notice-placard {
		position: absolute;
		bottom: 6%;
		left: 50%;
		transform: translateX(-50%);
		width: 90%;
		max-width: 480px;
		height: 150px;
		background: linear-gradient(135deg, #2a2622 0%, #1f1c19 100%);
		border-left: 3px solid #c45c4a;
		box-shadow:
			0 4px 20px rgba(0, 0, 0, 0.4),
			inset 0 1px 0 rgba(255, 255, 255, 0.05);
		border-radius: 2px;
		overflow: hidden;
	}

	.notice-placard.mobile {
		bottom: 4%;
		width: 94%;
		height: 140px;
	}

	/* Content is absolutely positioned so fade doesn't affect container size */
	.placard-content {
		position: absolute;
		inset: 0;
		padding: 1.25rem 1.5rem;
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
	}

	.notice-placard.mobile .placard-content {
		padding: 1rem 1.25rem;
	}

	.placard-empty {
		justify-content: center;
	}

	.placard-title {
		font-family: 'Source Sans 3', system-ui, sans-serif;
		font-size: 1.25rem;
		font-weight: 700;
		color: #ffffff;
		letter-spacing: 0.01em;
		margin: 0;
	}

	.placard-subtitle {
		font-family: 'Source Sans 3', system-ui, sans-serif;
		font-size: 0.9375rem;
		font-weight: 500;
		color: #d4d0c8;
		margin: 0;
	}

	.placard-excerpt {
		font-family: 'Courier Prime', 'Courier New', monospace;
		font-size: 1rem;
		font-weight: 500;
		font-style: italic;
		color: #e8715f;
		margin: 0.5rem 0 0 0;
		line-height: 1.5;
	}

	/* Mobile adjustments */
	@media (max-width: 640px) {
		.placard-title {
			font-size: 1rem;
		}

		.placard-subtitle {
			font-size: 0.8125rem;
		}

		.placard-excerpt {
			font-size: 0.875rem;
		}
	}
</style>
