<script lang="ts">
	import { onMount } from 'svelte';
	import GameMap from '$lib/components/GameMap.svelte';
	import WikiFiche from '$lib/components/WikiFiche.svelte';
	import Seo from '$lib/components/Seo.svelte';
	import { t } from '$lib/i18n/store.svelte';
	import { REGIONS } from '$lib/map/regions';
	import type { ExplorerLieu, Region } from '$lib/types';

	type Filtre = Region | 'TOUTES';

	let lieux = $state<ExplorerLieu[]>([]);
	let filtre = $state<Filtre>('TOUTES');
	let selection = $state<ExplorerLieu | null>(null);
	let erreur = $state(false);

	const lieuxFiltres = $derived(
		filtre === 'TOUTES' ? lieux : lieux.filter((l) => l.region === filtre)
	);
	const markers = $derived(
		lieuxFiltres.map((l) => ({
			// Id éphémère côté client (indice dans le catalogue) : /api/lieux n'expose
			// plus l'uuid du lieu, pour ne pas corréler un id de round avec sa commune (C4).
			id: String(lieux.indexOf(l)),
			lat: l.coordonnees.lat,
			lon: l.coordonnees.lon,
			label: `${l.nom} — ${l.commune}`
		}))
	);

	function ouvrir(id: string): void {
		selection = lieux[Number(id)] ?? null;
	}

	onMount(() => {
		void (async () => {
			try {
				const res = await fetch('/api/lieux');
				if (!res.ok) throw new Error(String(res.status));
				lieux = (await res.json()) as ExplorerLieu[];
			} catch {
				erreur = true;
			}
		})();
	});
</script>

<Seo title={t().explorer.titre} description={t().modes.explorerDesc} path="/explorer" />

<div class="explorer">
	<div class="filtres" role="group" aria-label={t().explorer.filtrer}>
		<button
			type="button"
			class:actif={filtre === 'TOUTES'}
			aria-pressed={filtre === 'TOUTES'}
			onclick={() => (filtre = 'TOUTES')}
		>
			{t().regions.TOUTES}
		</button>
		{#each REGIONS as r (r)}
			<button
				type="button"
				class:actif={filtre === r}
				aria-pressed={filtre === r}
				onclick={() => (filtre = r)}
			>
				{t().regions[r]}
			</button>
		{/each}
	</div>

	<div class="carte-explorer">
		{#if erreur}
			<p class="erreur">{t().jeu.erreur}</p>
		{:else}
			<GameMap interactive={false} {markers} onmarkerclick={ouvrir} />
		{/if}
	</div>

	<!-- Panneau latéral (desktop) / bottom sheet (mobile) -->
	<aside class="fiche" class:ouvert={!!selection} aria-live="polite">
		{#if selection}
			<button
				type="button"
				class="fermer"
				aria-label={t().explorer.fermer}
				onclick={() => (selection = null)}
			>
				✕
			</button>
			<figure class="fiche-photo">
				<img
					src={selection.photo.url}
					alt={selection.photo.alt}
					loading="lazy"
					decoding="async"
				/>
				<figcaption>{selection.photo.credit}</figcaption>
			</figure>
			<h1>{selection.nom}</h1>
			{#if selection.nom_creole && selection.nom_creole !== selection.nom}
				<p class="creole">{selection.nom_creole}</p>
			{/if}
			<p class="localisation">
				{t().resultat.commune} : {selection.commune} — {t().regions[selection.region]}
			</p>
			{#key selection.nom}
				<WikiFiche nom={selection.nom} wikidataId={selection.wikidata_id} />
			{/key}
		{:else}
			<p class="vide">{t().explorer.aucuneFiche}</p>
		{/if}
	</aside>
</div>

<style>
	.explorer {
		flex: 1;
		display: flex;
		flex-direction: column;
		position: relative;
		min-height: 0;
		overflow: hidden; /* la partie repliée du sheet ne doit pas agrandir la page */
	}

	.filtres {
		display: flex;
		gap: 0.4rem;
		flex-wrap: wrap;
		padding: 0.6rem 0.8rem;
		background: var(--oki-blanc);
		border-bottom: 1px solid var(--oki-sable-fonce);
	}

	.filtres button {
		border: 1.5px solid var(--oki-vert-clair);
		background: transparent;
		color: var(--oki-vert);
		border-radius: 999px;
		padding: 0.35rem 0.9rem;
		font-size: 0.88rem;
		font-weight: 650;
		cursor: pointer;
	}

	.filtres button.actif {
		background: var(--oki-vert);
		border-color: var(--oki-vert);
		color: #fff;
	}

	.carte-explorer {
		flex: 1;
		min-height: 0;
		padding: 0.6rem 0.6rem 3.6rem; /* réserve la bande de la poignée du sheet :
		   la fiche repliée ne recouvre jamais la carte, les sauts ni l'attribution */
	}

	.erreur {
		text-align: center;
		color: var(--oki-encre-doux);
	}

	/* Bottom sheet mobile : overlay dont les événements sont scopés à lui-même.
	   Glisse --dur-mesure --ease-ka (cadence gwoka), coupée en reduced-motion. */
	.fiche {
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		max-height: 62%;
		overflow-y: auto;
		background: var(--oki-blanc);
		border-radius: var(--oki-radius) var(--oki-radius) 0 0;
		box-shadow: 0 -4px 18px rgba(11, 61, 46, 0.2);
		padding: 1rem;
		transform: translateY(calc(100% - 3.2rem));
		transition: transform var(--dur-mesure) var(--ease-ka);
	}

	.fiche.ouvert {
		transform: translateY(0);
	}

	.fiche .vide {
		margin: 0;
		text-align: center;
		color: var(--oki-encre-doux);
		padding-bottom: 0.4rem;
	}

	.fermer {
		position: absolute;
		top: 0.6rem;
		right: 0.6rem;
		border: none;
		background: var(--oki-vert-doux);
		color: var(--oki-vert);
		width: 2rem;
		height: 2rem;
		border-radius: 50%;
		font-size: 1rem;
		cursor: pointer;
	}

	.fiche-photo {
		margin: 0 0 0.6rem;
	}

	.fiche-photo img {
		width: 100%;
		max-height: 200px;
		object-fit: cover;
		border-radius: var(--oki-radius-petit);
		display: block;
	}

	.fiche-photo figcaption {
		font-size: 0.72rem;
		color: var(--oki-encre-doux);
		margin-top: 0.2rem;
	}

	.fiche h1 {
		margin: 0;
		font-size: 1.3rem;
		color: var(--oki-vert);
	}

	.creole {
		margin: 0.1rem 0 0;
		font-style: italic;
		color: var(--oki-vert-clair);
	}

	.localisation {
		margin: 0.3rem 0 0.8rem;
		color: var(--oki-encre-doux);
		font-size: 0.92rem;
	}

	/* Desktop : panneau latéral droit EN FLUX (grille) — plus aucune bande
	   verticale par-dessus la carte, toute la carte reste cliquable. */
	@media (min-width: 768px) {
		.explorer {
			display: grid;
			grid-template-columns: minmax(0, 1fr) 360px;
			grid-template-rows: auto minmax(0, 1fr);
		}

		.filtres {
			grid-column: 1 / -1;
		}

		.carte-explorer {
			padding: 0.8rem;
			min-height: 0;
		}

		.fiche {
			position: static;
			transform: none;
			max-height: none;
			min-height: 0;
			border-radius: 0;
			border-left: 1px solid var(--oki-sable-fonce);
			box-shadow: none;
		}
	}

	@media (prefers-reduced-motion: reduce) {
		.fiche {
			transition: none;
		}
	}
</style>
