<script lang="ts">
	import Card from '$lib/Card.svelte';
	import StickyNote from '$lib/StickyNote.svelte';
	import { onMount } from 'svelte';

	interface CardData {
		id: number;
		frontImage: string;
		flipped: boolean;
		x: number;
		y: number;
		zIndex: number;
		inDeck: boolean;
		isRiskCategory?: boolean;
	}

	interface DeckConfig {
		name: string;
		backImage: string;
		cards: string[];
		riskCategories?: string[];
	}

	interface StickyNote {
		id: number;
		text: string;
		x: number;
		y: number;
		zIndex: number;
		color: string;
	}

	const deckConfigs: DeckConfig[] = [
		{
			name: 'Default',
			backImage: 'back.png',
			cards: Array.from({ length: 14 }, (_, i) => `front${i + 1}.png`)
		},
		{
			name: 'Risk Cards',
			backImage: 'risks/risiko_back.png',
			cards: [
				'risks/altsysteme_und_altlasten1.png',
				'risks/altsysteme_und_altlasten2.png',
				'risks/altsysteme_und_altlasten3.png',
				'risks/altsysteme_und_altlasten4.png',
				'risks/altsysteme_und_altlasten5.png',
				'risks/betrieb_und_deployment1.png',
				'risks/betrieb_und_deployment2.png',
				'risks/betrieb_und_deployment3.png',
				'risks/betrieb_und_deployment4.png',
				'risks/betrieb_und_deployment5.png',
				'risks/fremdsysteme_und_plattformen1.png',
				'risks/fremdsysteme_und_plattformen2.png',
				'risks/fremdsysteme_und_plattformen3.png',
				'risks/fremdsysteme_und_plattformen4.png',
				'risks/fremdsysteme_und_plattformen5.png',
				'risks/kompetenz_und_erfahrung1.png',
				'risks/kompetenz_und_erfahrung2.png',
				'risks/kompetenz_und_erfahrung3.png',
				'risks/kompetenz_und_erfahrung4.png',
				'risks/kompetenz_und_erfahrung5.png',
				'risks/orga_und_prozesse1.png',
				'risks/orga_und_prozesse2.png',
				'risks/orga_und_prozesse3.png',
				'risks/orga_und_prozesse4.png',
				'risks/orga_und_prozesse5.png',
				'risks/softwareloesung1.png',
				'risks/softwareloesung2.png',
				'risks/softwareloesung3.png',
				'risks/softwareloesung4.png',
				'risks/softwareloesung5.png',
				'risks/weiche_faktoren1.png',
				'risks/weiche_faktoren2.png',
				'risks/weiche_faktoren3.png',
				'risks/weiche_faktoren4.png',
				'risks/weiche_faktoren5.png',
				'risks/zielsetzung1.png',
				'risks/zielsetzung2.png',
				'risks/zielsetzung3.png',
				'risks/zielsetzung4.png',
				'risks/zielsetzung5.png'
			],
			riskCategories: [
				'altsysteme_und_altlasten',
				'betrieb_und_deployment',
				'fremdsysteme_und_plattformen',
				'kompetenz_und_erfahrung',
				'orga_und_prozesse',
				'softwareloesung',
				'weiche_faktoren',
				'zielsetzung'
			]
		}
	];

	let selectedDeck = $state(0);
	let shuffleMode = $state('normal');
	let currentDeckConfig = $derived(deckConfigs[selectedDeck]);
	let backImage = $derived(currentDeckConfig.backImage);

	let deckPosition = $state({ x: 50, y: 300 });
	let canvasOffset = $state({ x: 0, y: 0 });
	let isDragging = $state(false);
	let dragStart = $state({ x: 0, y: 0 });
	let dragStartOffset = $state({ x: 0, y: 0 });

	let cards = $state<CardData[]>([]);
	let maxZIndex = $state(0);
	let stickyNotes = $state<StickyNote[]>([]);
	let nextNoteId = $state(1);
	let noteColors = ['#ffeb3b', '#4caf50', '#2196f3', '#ff9800', '#e91e63', '#9c27b0'];

	function initializeDeck() {
		const config = deckConfigs[selectedDeck];
		cards = config.cards.map((image, index) => ({
			id: index + 1,
			frontImage: image,
			flipped: true,
			x: deckPosition.x + index * 2,
			y: deckPosition.y + index * 2,
			zIndex: index,
			inDeck: true,
			isRiskCategory: selectedDeck === 1 && image.includes('1.png')
		}));
		maxZIndex = cards.length;
	}

	onMount(() => {
		initializeDeck();
	});

	function handleDeckChange() {
		initializeDeck();
	}

	function handleCardMove(id: number, x: number, y: number) {
		const card = cards.find(c => c.id === id);
		if (card) {
			card.x = x;
			card.y = y;
			card.zIndex = ++maxZIndex;
		}
	}

	function handleCardDrop(id: number, x: number, y: number) {
		const card = cards.find(c => c.id === id);
		if (card) {
			// Calculate card center position (card is 220x300px)
			const cardCenterX = x + 110;
			const cardCenterY = y + 150;
			
			// Check if card center is dropped on deck area
			if (
				cardCenterX >= deckPosition.x && 
				cardCenterX <= deckPosition.x + 220 && 
				cardCenterY >= deckPosition.y && 
				cardCenterY <= deckPosition.y + 300 &&
				!card.inDeck
			) {
				// Move card to top of deck
				const deckCards = cards.filter(c => c.inDeck);
				const topZ = deckCards.length > 0 ? Math.max(...deckCards.map(c => c.zIndex)) + 1 : 0;
				
				card.x = deckPosition.x + topZ * 2;
				card.y = deckPosition.y + topZ * 2;
				card.zIndex = topZ;
				card.flipped = true;
				card.inDeck = true;
			} else if (card.inDeck) {
				// Card was moved out of deck
				card.inDeck = false;
			}
		}
	}

	function handleCardClick(id: number) {
		const card = cards.find(c => c.id === id);
		if (card) {
			card.zIndex = ++maxZIndex;
		}
	}

	function shuffleDeck() {
		const deckCards = cards.filter(card => card.inDeck);
		if (deckCards.length === 0) return;
		
		if (selectedDeck === 1) {
			if (shuffleMode === 'shuffle-only-risks') {
				shuffleOnlyRisks();
			} else if (shuffleMode === 'shuffle-per-category') {
				shufflePerCategory();
			} else {
				normalShuffle(deckCards);
			}
		} else {
			normalShuffle(deckCards);
		}
	}

	function normalShuffle(deckCards: CardData[]) {
		for (let i = deckCards.length - 1; i > 0; i--) {
			const j = Math.floor(Math.random() * (i + 1));
			[deckCards[i], deckCards[j]] = [deckCards[j], deckCards[i]];
		}

		deckCards.forEach((card, index) => {
			card.x = deckPosition.x + index * 2;
			card.y = deckPosition.y + index * 2;
			card.zIndex = index;
			card.flipped = true;
		});
	}

	function shuffleOnlyRisks() {
		const deckCards = cards.filter(card => card.inDeck);
		const riskCategories = deckCards.filter(card => card.isRiskCategory);
		const riskCards = deckCards.filter(card => !card.isRiskCategory);
		
		for (let i = riskCards.length - 1; i > 0; i--) {
			const j = Math.floor(Math.random() * (i + 1));
			[riskCards[i], riskCards[j]] = [riskCards[j], riskCards[i]];
		}
		
		const shuffled = [...riskCategories, ...riskCards];
		shuffled.reverse();
		
		const numCategories = riskCategories.length;
		const totalCards = shuffled.length;
		
		shuffled.forEach((card, index) => {
			if (index >= totalCards - numCategories) {
				const categoryIndex = index - (totalCards - numCategories);
				card.x = 50 + 330 + (categoryIndex % 6) * 240;
				card.y = 50 + Math.floor(categoryIndex / 6) * 320;
				card.zIndex = index;
				card.flipped = false;
				card.inDeck = false;
			} else {
				card.x = deckPosition.x + index * 2;
				card.y = deckPosition.y + index * 2;
				card.zIndex = index;
				card.flipped = true;
				card.inDeck = true;
			}
		});
	}

	function shufflePerCategory() {
		const deckCards = cards.filter(card => card.inDeck);
		const categories = currentDeckConfig.riskCategories || [];
		const shuffledDeck: CardData[] = [];
		
		for (const category of categories) {
			const categoryCard = deckCards.find(card => card.frontImage.includes(`${category}1.png`));
			const categoryRisks = deckCards.filter(card => 
				card.frontImage.includes(category) && !card.frontImage.includes('1.png')
			);
			
			for (let i = categoryRisks.length - 1; i > 0; i--) {
				const j = Math.floor(Math.random() * (i + 1));
				[categoryRisks[i], categoryRisks[j]] = [categoryRisks[j], categoryRisks[i]];
			}
			
			if (categoryCard) shuffledDeck.push(categoryCard);
			shuffledDeck.push(...categoryRisks);
		}
		
		shuffledDeck.reverse();
		
		shuffledDeck.forEach((card, index) => {
			card.x = deckPosition.x + index * 2;
			card.y = deckPosition.y + index * 2;
			card.zIndex = index;
			card.flipped = true;
		});
	}

	function collectToDeck() {
		cards.forEach((card, index) => {
			card.x = deckPosition.x + index * 2;
			card.y = deckPosition.y + index * 2;
			card.zIndex = index;
			card.flipped = true;
			card.inDeck = true;
		});
	}

	function dealCards() {
		cards.forEach((card, index) => {
			card.x = 50 + 330 + (index % 6) * 240;
			card.y = 50 + Math.floor(index / 6) * 320;
			card.zIndex = index;
			card.flipped = false;
			card.inDeck = false;
		});
	}

	function flipAllCards() {
		cards.forEach(card => {
			card.flipped = !card.flipped;
		});
	}

	function handleCanvasWheel(event: WheelEvent) {
		event.preventDefault();
		const scrollSpeed = 1;
		canvasOffset.x -= event.deltaX * scrollSpeed;
		canvasOffset.y -= event.deltaY * scrollSpeed;
		
		canvasOffset.x = Math.max(-2000, Math.min(2000, canvasOffset.x));
		canvasOffset.y = Math.max(-2000, Math.min(2000, canvasOffset.y));
	}

	function handleCanvasMouseDown(event: MouseEvent) {
		if (event.button === 1 || event.button === 2) {
			event.preventDefault();
			isDragging = true;
			dragStart.x = event.clientX;
			dragStart.y = event.clientY;
			dragStartOffset.x = canvasOffset.x;
			dragStartOffset.y = canvasOffset.y;
		}
	}

	function handleCanvasMouseMove(event: MouseEvent) {
		if (isDragging) {
			event.preventDefault();
			const deltaX = event.clientX - dragStart.x;
			const deltaY = event.clientY - dragStart.y;
			
			canvasOffset.x = Math.max(-2000, Math.min(2000, dragStartOffset.x + deltaX));
			canvasOffset.y = Math.max(-2000, Math.min(2000, dragStartOffset.y + deltaY));
		}
	}

	function handleCanvasMouseUp(event: MouseEvent) {
		if (event.button === 1 || event.button === 2) {
			isDragging = false;
		}
	}

	function handleCanvasContextMenu(event: MouseEvent) {
		event.preventDefault();
	}

	function addStickyNote() {
		const randomColor = noteColors[Math.floor(Math.random() * noteColors.length)];
		const newNote: StickyNote = {
			id: nextNoteId++,
			text: 'New note',
			x: 400 - canvasOffset.x,
			y: 200 - canvasOffset.y,
			zIndex: ++maxZIndex,
			color: randomColor
		};
		stickyNotes.push(newNote);
	}

	function updateStickyNote(id: number, text: string) {
		const note = stickyNotes.find(n => n.id === id);
		if (note) {
			note.text = text;
		}
	}

	function moveStickyNote(id: number, x: number, y: number) {
		const note = stickyNotes.find(n => n.id === id);
		if (note) {
			note.x = x;
			note.y = y;
			note.zIndex = ++maxZIndex;
		}
	}

	function deleteStickyNote(id: number) {
		const index = stickyNotes.findIndex(n => n.id === id);
		if (index >= 0) {
			stickyNotes.splice(index, 1);
		}
	}

	function exportCanvas() {
		const canvasState = {
			selectedDeck,
			shuffleMode,
			cards: cards.map(card => ({...card})),
			stickyNotes: stickyNotes.map(note => ({...note})),
			canvasOffset,
			deckPosition,
			maxZIndex,
			nextNoteId,
			timestamp: new Date().toISOString()
		};

		const dataStr = JSON.stringify(canvasState, null, 2);
		const dataBlob = new Blob([dataStr], { type: 'application/json' });
		const url = URL.createObjectURL(dataBlob);
		
		const link = document.createElement('a');
		link.href = url;
		link.download = `canvas-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.json`;
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);
		URL.revokeObjectURL(url);
	}

	function importCanvas() {
		const input = document.createElement('input');
		input.type = 'file';
		input.accept = '.json';
		input.onchange = (event) => {
			const file = (event.target as HTMLInputElement).files?.[0];
			if (!file) return;

			const reader = new FileReader();
			reader.onload = (e) => {
				try {
					const canvasState = JSON.parse(e.target?.result as string);
					
					// Validate the imported data structure
					if (!canvasState.cards || !Array.isArray(canvasState.cards)) {
						alert('Invalid canvas file format');
						return;
					}

					// Restore state
					selectedDeck = canvasState.selectedDeck || 0;
					shuffleMode = canvasState.shuffleMode || 'normal';
					cards = canvasState.cards || [];
					stickyNotes = canvasState.stickyNotes || [];
					canvasOffset = canvasState.canvasOffset || { x: 0, y: 0 };
					deckPosition = canvasState.deckPosition || { x: 50, y: 300 };
					maxZIndex = canvasState.maxZIndex || cards.length;
					nextNoteId = canvasState.nextNoteId || 1;

				} catch (error) {
					alert('Error reading canvas file: ' + error);
				}
			};
			reader.readAsText(file);
		};
		document.body.appendChild(input);
		input.click();
		document.body.removeChild(input);
	}
</script>

<div class="game-container">
	<div class="controls">
		<div class="control-group">
			<label for="deck-select">Deck:</label>
			<select id="deck-select" bind:value={selectedDeck} onchange={handleDeckChange}>
				{#each deckConfigs as config, index}
					<option value={index}>{config.name}</option>
				{/each}
			</select>
		</div>
		
		{#if selectedDeck === 1}
			<div class="control-group">
				<label for="shuffle-mode">Shuffle:</label>
				<select id="shuffle-mode" bind:value={shuffleMode}>
					<option value="normal">Normal</option>
					<option value="shuffle-only-risks">Only Risks</option>
					<option value="shuffle-per-category">Per Category</option>
				</select>
			</div>
		{/if}
		
		<button onclick={collectToDeck}>Collect to Deck</button>
		<button onclick={shuffleDeck}>Shuffle Deck</button>
		<button onclick={dealCards}>Deal Cards</button>
		<button onclick={flipAllCards}>Flip All</button>
		<button onclick={addStickyNote}>Add Note</button>
		<button onclick={exportCanvas}>Export</button>
		<button onclick={importCanvas}>Import</button>
	</div>

	<div 
		class="game-area"
		onwheel={handleCanvasWheel}
		onmousedown={handleCanvasMouseDown}
		onmousemove={handleCanvasMouseMove}
		onmouseup={handleCanvasMouseUp}
		oncontextmenu={handleCanvasContextMenu}
	>
		<div 
			class="canvas-content" 
			style="transform: translate({canvasOffset.x}px, {canvasOffset.y}px);"
		>
			{#each cards as card (card.id)}
				<Card
					{...card}
					backImage={card.isRiskCategory ? 'risks/risikocat_back.png' : backImage}
					canvasOffset={canvasOffset}
					bind:flipped={card.flipped}
					bind:x={card.x}
					bind:y={card.y}
					bind:zIndex={card.zIndex}
					onMove={handleCardMove}
					onClick={handleCardClick}
					onDrop={handleCardDrop}
				/>
			{/each}

			{#each stickyNotes as note (note.id)}
				<StickyNote
					{...note}
					canvasOffset={canvasOffset}
					bind:text={note.text}
					bind:x={note.x}
					bind:y={note.y}
					bind:zIndex={note.zIndex}
					onMove={moveStickyNote}
					onUpdate={updateStickyNote}
					onDelete={deleteStickyNote}
				/>
			{/each}

			<div 
				class="deck-area" 
				style="left: {deckPosition.x}px; top: {deckPosition.y}px;"
			>
				Deck
			</div>
		</div>
	</div>
</div>

<style>
	.game-container {
		width: 100vw;
		height: 100vh;
		overflow: hidden;
		background: #161616;
		font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
	}

	.controls {
		position: fixed;
		top: 20px;
		right: 20px;
		display: flex;
		gap: 10px;
		z-index: 2000;
		align-items: center;
		flex-wrap: wrap;
	}
	
	.control-group {
		display: flex;
		align-items: center;
		gap: 5px;
		background: rgba(255, 255, 255, 0.9);
		padding: 8px 12px;
		border-radius: 27px;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
	}
	
	.control-group label {
		font-weight: 600;
		font-size: 14px;
		color: #333;
	}
	
	.control-group select {
		padding: 4px 8px;
		border: 1px solid #ccc;
		border-radius: 4px;
		background: white;
		font-size: 14px;
		cursor: pointer;
	}

	.controls button {
		padding: 10px 15px;
		background: rgba(255, 255, 255, 0.9);
		border: none;
		border-radius: 27px;
		cursor: pointer;
		font-weight: 600;
		transition: all 0.2s ease;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
	}

	.controls button:hover {
		background: white;
		transform: translateY(-1px);
		box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
	}

	.game-area {
		position: relative;
		width: 100%;
		height: 100%;
		overflow: hidden;
		cursor: grab;
	}

	.game-area:active {
		cursor: grabbing;
	}

	.canvas-content {
		position: relative;
		width: 500vw;
		height: 500vh;
		min-width: 500vw;
		min-height: 500vh;
	}

	.deck-area {
		position: absolute;
		width: 220px;
		height: 300px;
		border: 3px dashed rgba(255, 255, 255, 0.5);
		border-radius: 25px;
		display: flex;
		align-items: center;
		justify-content: center;
		color: rgba(255, 255, 255, 0.7);
		font-weight: bold;
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
	}
</style>
