<script lang="ts">
	import { onMount } from 'svelte';
	import { get } from 'svelte/store';
	import CanvasMap from '../lib/components/canvas/CanvasMap.svelte';
	import UserProfileButton from '../lib/components/user/UserProfileButton.svelte';
	import PaintButton from '../lib/components/canvas/PaintButton.svelte';
	import ActionButtons from '../lib/components/layout/ActionButtons.svelte';
	import MapControls from '../lib/components/layout/MapControls.svelte';
	import ColorPaletteModal from '../lib/components/canvas/ColorPaletteModal.svelte';
	import PixelInfoPopup from '../lib/components/canvas/PixelInfoPopup.svelte';
	import { api, ApiError } from '../lib/api/client';
	import { currentUser, currentCharges } from '../lib/stores/user';
	import { selectedColor } from '../lib/stores/canvas';
	import { online } from '../lib/stores/global';

	interface SelectedPixel {
		tileX: number;
		tileY: number;
		x: number;
		y: number;
		latlng: { lat: number; lng: number };
	}

	const SEASON = 's0';

	let mapRef: CanvasMap | null = null;
	let selected: SelectedPixel | null = null;
	let pixelInfo: any = null;
	let loadingPixel = false;
	let painting = false;
	let errorMessage = '';
	let successMessage = '';
	let showColorPalette = false;

	onMount(() => {
		currentUser.fetch();
	});

	async function handlePixel(event: CustomEvent<SelectedPixel>) {
		selected = event.detail;
		errorMessage = '';
		successMessage = '';
		pixelInfo = null;
		await loadPixelInfo(event.detail);
	}

	async function loadPixelInfo(selection: SelectedPixel) {
		loadingPixel = true;
		try {
			pixelInfo = await api.getPixelInfo(
				SEASON,
				selection.tileX,
				selection.tileY,
				selection.x,
				selection.y
			);
		} catch (error) {
			console.error('Failed to load pixel info:', error);
		} finally {
			loadingPixel = false;
		}
	}

	function canPaint(): boolean {
		const user = get(currentUser);
		if (!user || !selected) return false;
		const color = get(selectedColor);
		if (color === 0) return false;
		const charges = get(currentCharges);
		return charges > 0 && get(online);
	}

	async function paint() {
		if (!selected) return;
		const user = get(currentUser);
		if (!user) {
			errorMessage = 'Login required to paint.';
			return;
		}
		const color = get(selectedColor);
		if (color === 0) {
			errorMessage = 'Select a color to paint.';
			return;
		}
		const charges = get(currentCharges);
		if (charges <= 0) {
			errorMessage = 'Not enough charges.';
			return;
		}

		painting = true;
		errorMessage = '';
		successMessage = '';

		try {
			await api.paintPixels(SEASON, selected.tileX, selected.tileY, {
				colors: [color],
				coords: [selected.x, selected.y]
			});
			await currentUser.fetch();
			await loadPixelInfo(selected);
			mapRef?.refreshTiles();
			successMessage = 'Pixel painted!';
			setTimeout(() => (successMessage = ''), 2000);
		} catch (error) {
			if (error instanceof ApiError) {
				errorMessage = error.message;
			} else {
				errorMessage = 'Failed to paint pixel.';
			}
		} finally {
			painting = false;
		}
	}
</script>

<svelte:head>
	<title>wplace - Paint the World</title>
</svelte:head>

<!-- Full-screen map container -->
<div class="disable-pinch-zoom relative h-screen w-screen overflow-hidden">
	<!-- Map -->
	<div class="h-screen w-screen">
		<CanvasMap bind:this={mapRef} on:pixel={handlePixel} />
	</div>

	<!-- Top-right: User profile & actions -->
	<div class="absolute right-2 top-2 z-30">
		<div class="flex flex-col gap-4 items-center">
			<UserProfileButton />
			<ActionButtons />
		</div>
	</div>

	<!-- Top-left: Map controls -->
	<div class="absolute left-2 top-2 z-30">
		<MapControls
			on:zoom={(e) => {
				if (e.detail.direction === 'in') mapRef?.getMap()?.zoomIn();
				else mapRef?.getMap()?.zoomOut();
			}}
			on:info={() => alert('wplace - Collaborative pixel art canvas')}
		/>
	</div>

	<!-- Bottom-center: Paint button and tooltip -->
	<div class="absolute bottom-3 left-1/2 z-30 -translate-x-1/2 flex flex-col items-center gap-2">
		<!-- Tooltip message -->
		{#if selected && !painting}
			<div class="bg-base-100 rounded-full px-4 py-2 shadow-md flex items-center gap-2 text-sm">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					viewBox="0 -960 960 960"
					fill="currentColor"
					class="size-4"
				>
					<path
						d="M240-120q-45 0-89-22t-71-58q26 0 53-20.5t27-59.5q0-50 35-85t85-35q50 0 85 35t35 85q0 66-47 113t-113 47Zm230-240L360-470l358-358q11-11 27.5-11.5T774-828l54 54q12 12 12 28t-12 28L470-360Z"
					/>
				</svg>
				Click or hold <kbd class="kbd kbd-sm">SPACE</kbd> to paint.
			</div>
		{/if}

		<PaintButton
			disabled={!canPaint() || painting}
			{painting}
			on:click={paint}
			on:openPalette={() => (showColorPalette = true)}
		/>
	</div>

	<!-- Bottom-left: Toggle art opacity -->
	<div class="absolute bottom-3 left-3 z-30">
		<button
			title="Toggle art opacity"
			class="btn btn-lg btn-square sm:btn-xl shadow-md text-base-content/80"
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 -960 960 960"
				fill="currentColor"
				class="size-5"
			>
				<path
					d="M440-440v-80h80v80h-80Zm-80 80v-80h80v80h-80Zm160 0v-80h80v80h-80Zm80-80v-80h80v80h-80Zm-320 0v-80h80v80h-80Zm-80 320q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm80-80h80v-80h-80v80Zm160 0h80v-80h-80v80Zm320 0v-80 80Zm-560-80h80v-80h80v80h80v-80h80v80h80v-80h80v80h80v-80h-80v-80h80v-320H200v320h80v80h-80v80Zm0 80v-560 560Zm560-240v80-80ZM600-280v80h80v-80h-80Z"
				/>
			</svg>
		</button>
	</div>

	<!-- Bottom-right: My location -->
	<div class="absolute bottom-3 right-3 z-30">
		<button title="My location" class="btn btn-lg btn-square sm:btn-xl shadow-md">
			<div class="relative">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					viewBox="0 -960 960 960"
					fill="currentColor"
					class="size-5.5 fill-red-400"
				>
					<path
						d="M440-40v-80q-125-14-214.5-103.5T122-438H42v-80h80q14-125 103.5-214.5T440-836v-80h80v80q125 14 214.5 103.5T838-518h80v80h-80q-14 125-103.5 214.5T520-120v80h-80Zm40-158q116 0 198-82t82-198q0-116-82-198t-198-82q-116 0-198 82t-82 198q0 116 82 198t198 82Z"
					/>
				</svg>
				<span class="center-absolute absolute text-[10px] text-red-400">?</span>
			</div>
		</button>
	</div>

	<!-- Pixel Info Popup -->
	{#if selected && pixelInfo && !showColorPalette}
		<div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-40">
			<PixelInfoPopup
				{pixelInfo}
				coords={{ tileX: selected.tileX, tileY: selected.tileY, x: selected.x, y: selected.y }}
				on:paint={paint}
				on:favorite={() => console.log('Favorite')}
				on:share={() => console.log('Share')}
			/>
		</div>
	{/if}

	<!-- Color Palette Modal -->
	{#if showColorPalette}
		<ColorPaletteModal on:close={() => (showColorPalette = false)} />
	{/if}

	<!-- Success/Error Messages -->
	{#if successMessage}
		<div class="absolute top-20 left-1/2 -translate-x-1/2 z-40">
			<div class="alert alert-success shadow-lg">
				<span>{successMessage}</span>
			</div>
		</div>
	{/if}

	{#if errorMessage}
		<div class="absolute top-20 left-1/2 -translate-x-1/2 z-40">
			<div class="alert alert-error shadow-lg">
				<span>{errorMessage}</span>
			</div>
		</div>
	{/if}
</div>

<style>
	.disable-pinch-zoom {
		touch-action: pan-x pan-y;
	}

	.center-absolute {
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
	}

	:global(.size-5\.5) {
		width: 1.375rem;
		height: 1.375rem;
	}
</style>
