<script lang="ts">
	import type { Bundle, Locale } from '$lib/i18n';

	/**
	 * HostingVillage — scène SVG isométrique « village créole ».
	 * Chaque bâtiment est une instance hébergée OKI (lien externe) :
	 *   BOKANTE (Mastodon)  → case créole à ka
	 *   GADE (PeerTube)     → karbay
	 *   NIYAJ (Nextcloud)   → silo nuage
	 *   KUTE (Castopod)     → case au panneau « KUTE » + antenne
	 * Fallback accessible : grille de cards HTML (miroir sémantique)
	 * affichée à la place de la scène si prefers-reduced-motion ou ≤ 640 px.
	 * DOM/SVG uniquement, aucun WebGL, aucune dépendance (playbook P3).
	 */

	let { t, locale }: { t: Bundle; locale: Locale } = $props();

	interface HostedService {
		name: string;
		platform: string;
		description: string;
		url: string;
		linkText: string;
	}

	/** Secours si le bundle ne fournit pas l'entrée (contenu legacy stable). */
	const DEFAULTS: Record<string, HostedService> = {
		BOKANTE: {
			name: 'BOKANTE',
			platform: 'Mastodon',
			description: '',
			url: 'https://bokante.o-k-i.net',
			linkText: 'BOKANTE'
		},
		GADE: {
			name: 'GADE',
			platform: 'PeerTube',
			description: '',
			url: 'https://gade.o-k-i.net',
			linkText: 'GADE'
		},
		NIYAJ: {
			name: 'NIYAJ',
			platform: 'Nextcloud',
			description: '',
			url: 'https://niyaj.o-k-i.net',
			linkText: 'NIYAJ'
		},
		KUTE: {
			name: 'KUTE',
			platform: 'Castopod',
			description: '',
			url: 'https://kute.o-k-i.net/',
			linkText: 'KUTE'
		}
	};

	// Les instances de la section « Services hébergés » vivent dans t.services.items
	let items = $derived((t.services?.items ?? []) as HostedService[]);

	function svc(name: string): HostedService {
		return items.find((i) => i.name?.toUpperCase() === name) ?? DEFAULTS[name];
	}

	let bokante = $derived(svc('BOKANTE'));
	let gade = $derived(svc('GADE'));
	let niyaj = $derived(svc('NIYAJ'));
	let kute = $derived(svc('KUTE'));

	let sceneLabel = $derived(
		locale === 'en'
			? 'Isometric Creole village of OKI hosted services: each building is a link to an instance.'
			: 'Village créole isométrique des services hébergés OKI : chaque bâtiment est un lien vers une instance.'
	);
</script>

<div class="hosting-village">
	<!-- ── Scène isométrique (masquée si reduced-motion ou ≤ 640 px) ── -->
	<div class="village-scene">
		<svg viewBox="0 0 960 540" width="100%" role="group" aria-label={sceneLabel}>
			<!-- Cadre nuit -->
			<rect class="sky" x="0" y="0" width="960" height="540" rx="6" />
			<!-- Étoiles angulaires -->
			<rect class="star" x="120" y="60" width="3" height="3" />
			<rect class="star" x="210" y="118" width="3" height="3" />
			<rect class="star" x="700" y="58" width="3" height="3" />
			<rect class="star" x="822" y="138" width="3" height="3" />
			<rect class="star" x="902" y="66" width="3" height="3" />
			<rect class="star" x="64" y="182" width="3" height="3" />
			<rect class="star" x="770" y="206" width="3" height="3" />
			<rect class="star" x="420" y="64" width="3" height="3" />

			<!-- Rivage puis sol en losange (arêtes à 30°) -->
			<polygon class="shore" points="480,133 860,352 480,571 100,352" />
			<polygon class="ground" points="480,138 830,340 480,542 130,340" />
			<!-- Place centrale + flambeaux -->
			<polygon class="plaza" points="480,321 600,390 480,459 360,390" />
			<polygon class="win" points="420,386.5 423.5,390 420,393.5 416.5,390" />
			<polygon class="win win-delay" points="540,386.5 543.5,390 540,393.5 536.5,390" />
			<polygon class="win" points="480,344.5 483.5,348 480,351.5 476.5,348" />

			<!-- ══ NIYAJ — Nextcloud : silo nuage (arrière-plan, gauche) ══ -->
			<a
				class="bldg"
				href={niyaj.url}
				target="_blank"
				rel="noopener noreferrer"
				aria-label="{niyaj.name} — {niyaj.platform}"
			>
				<g class="bldg-art">
					<path
						class="silo-body"
						d="M234,290 L234,190 L306,190 L306,290 A36,20.8 0 0 1 234,290 Z"
					/>
					<path class="roof-or" d="M234,190 A36,32 0 0 1 306,190 Z" />
					<line class="roof-line" x1="234" y1="190" x2="306" y2="190" />
					<rect class="win" x="250" y="218" width="10" height="10" />
					<rect class="win win-delay" x="272" y="246" width="10" height="10" />
					<rect class="door" x="260" y="258" width="18" height="32" />
					<!-- Nuage angulaire au-dessus du silo -->
					<rect class="cloud" x="244" y="134" width="52" height="12" />
					<rect class="cloud" x="254" y="122" width="30" height="12" />
					<rect class="cloud" x="268" y="112" width="18" height="10" />
					<rect class="cloud" x="258" y="150" width="3" height="5" />
					<rect class="cloud" x="276" y="148" width="3" height="5" />
					<path
						class="bldg-outline"
						d="M234,190 A36,32 0 0 1 306,190 L306,290 A36,20.8 0 0 1 234,290 Z"
					/>
				</g>
				<g class="bldg-label">
					<rect class="label-plaque" x="186" y="70" width="168" height="24" rx="3" />
					<text class="label-text" x="270" y="87">{niyaj.name} — {niyaj.platform}</text>
				</g>
			</a>

			<!-- ══ GADE — PeerTube : karbay (arrière-plan, droite) ══ -->
			<a
				class="bldg"
				href={gade.url}
				target="_blank"
				rel="noopener noreferrer"
				aria-label="{gade.name} — {gade.platform}"
			>
				<g class="bldg-art">
					<rect class="post" x="657" y="188" width="6" height="72" />
					<polygon class="deck-top" points="660,262 729,302 660,342 591,302" />
					<polygon class="deck-left" points="591,302 660,342 660,350 591,310" />
					<polygon class="deck-right" points="660,342 729,302 729,310 660,350" />
					<rect class="post" x="570" y="238" width="6" height="72" />
					<rect class="post" x="744" y="238" width="6" height="72" />
					<rect class="post" x="657" y="288" width="6" height="72" />
					<polygon class="roof-vert-dark" points="566,238 660,292 660,132" />
					<polygon class="roof-vert" points="660,292 754,238 660,132" />
					<line class="roof-line" x1="660" y1="132" x2="660" y2="292" />
					<!-- Lanterne suspendue -->
					<line class="lantern-cord" x1="640" y1="262" x2="640" y2="274" />
					<rect class="win" x="635" y="274" width="10" height="12" />
					<path
						class="bldg-outline"
						d="M660,132 L754,238 L750,238 L750,310 L729,310 L660,350 L591,310 L570,310 L570,238 L566,238 Z"
					/>
				</g>
				<g class="bldg-label">
					<rect class="label-plaque" x="576" y="92" width="168" height="24" rx="3" />
					<text class="label-text" x="660" y="109">{gade.name} — {gade.platform}</text>
				</g>
			</a>

			<!-- ══ BOKANTE — Mastodon : case créole à ka (avant-plan, gauche) ══ -->
			<a
				class="bldg"
				href={bokante.url}
				target="_blank"
				rel="noopener noreferrer"
				aria-label="{bokante.name} — {bokante.platform}"
			>
				<g class="bldg-art">
					<polygon class="wall-left" points="312,430 390,475 390,420 312,375" />
					<polygon class="wall-right" points="390,475 468,430 468,375 390,420" />
					<line class="lamella" x1="338" y1="390" x2="338" y2="445" />
					<line class="lamella" x1="364" y1="405" x2="364" y2="460" />
					<line class="lamella" x1="410" y1="409" x2="410" y2="464" />
					<line class="lamella" x1="429" y1="397.5" x2="429" y2="452.5" />
					<line class="lamella" x1="448" y1="386" x2="448" y2="441" />
					<polygon class="win" points="330,404 348,414 348,428 330,418" />
					<polygon class="win win-delay" points="430,410 446,401 446,415 430,424" />
					<polygon class="door" points="398,470 416,460 416,430 398,440" />
					<rect class="door-knob" x="410" y="444" width="3" height="3" />
					<polygon class="roof-rouge-dark" points="293,375 390,431 390,283" />
					<polygon class="roof-rouge" points="390,431 487,375 390,283" />
					<line class="roof-line" x1="390" y1="283" x2="390" y2="431" />
					<!-- Ka (tambour gwoka) devant la case -->
					<path class="drum" d="M405,468 L405,490 A10,5.8 0 0 0 425,490 L425,468 Z" />
					<ellipse class="drum-top" cx="415" cy="468" rx="10" ry="5.8" />
					<path
						class="bldg-outline"
						d="M390,283 L487,375 L468,375 L468,430 L390,475 L312,430 L312,375 L293,375 Z"
					/>
				</g>
				<g class="bldg-label">
					<rect class="label-plaque" x="316" y="232" width="168" height="24" rx="3" />
					<text class="label-text" x="400" y="249">{bokante.name} — {bokante.platform}</text>
				</g>
			</a>

			<!-- ══ KUTE — Castopod : case au panneau « KUTE » + antenne (avant-plan, droite) ══ -->
			<a
				class="bldg"
				href={kute.url}
				target="_blank"
				rel="noopener noreferrer"
				aria-label="{kute.name} — {kute.platform}"
			>
				<g class="bldg-art">
					<polygon class="wall-left" points="544,440 600,478 600,432 544,394" />
					<polygon class="wall-right" points="600,478 676,440 676,394 600,432" />
					<line class="lamella" x1="572" y1="413" x2="572" y2="459" />
					<line class="lamella" x1="625" y1="419" x2="625" y2="465" />
					<line class="lamella" x1="650" y1="407" x2="650" y2="453" />
					<polygon class="win" points="560,414 574,422 574,434 560,426" />
					<polygon class="door" points="608,474 624,465 624,431 608,440" />
					<!-- Panneau « KUTE » sur la façade gauche -->
					<polygon class="sign" points="548,404 592,429 592,443 548,418" />
					<text
						class="sign-text"
						transform="matrix(1,0.577,0,1,552,416)"
						x="0"
						y="0">KUTE</text
					>
					<polygon class="roof-rouge-dark" points="517,384 600,432 600,304" />
					<polygon class="roof-rouge" points="600,432 683,384 600,304" />
					<line class="roof-line" x1="600" y1="304" x2="600" y2="432" />
					<!-- Antenne d'émission (podcast) -->
					<line class="antenna" x1="600" y1="304" x2="600" y2="284" />
					<line class="antenna-tick" x1="600" y1="284" x2="593" y2="276" />
					<line class="antenna-tick" x1="600" y1="284" x2="607" y2="276" />
					<line class="antenna-tick" x1="588" y1="270" x2="582" y2="262" />
					<line class="antenna-tick" x1="612" y1="270" x2="618" y2="262" />
					<path
						class="bldg-outline"
						d="M600,304 L683,384 L676,394 L676,440 L600,478 L544,440 L544,394 L517,384 Z"
					/>
				</g>
				<g class="bldg-label">
					<rect class="label-plaque" x="516" y="496" width="168" height="24" rx="3" />
					<text class="label-text" x="600" y="513">{kute.name} — {kute.platform}</text>
				</g>
			</a>
		</svg>
	</div>

	<!-- ── Fallback : grille de cards (miroir sémantique de la scène) ── -->
	<ul class="village-fallback" role="list">
		{#each items as item (item.name)}
			<li class="card vf-card">
				<div class="vf-head">
					<h3>{item.name}</h3>
					<span class="tag">{item.platform}</span>
				</div>
				<p class="vf-desc">{item.description}</p>
				<a class="vf-link" href={item.url} target="_blank" rel="noopener noreferrer"
					>{item.linkText}</a
				>
			</li>
		{/each}
	</ul>
</div>

<style>
	.hosting-village {
		margin-top: var(--space-4);
	}

	.village-scene svg {
		display: block;
		width: 100%;
		height: auto;
	}

	/* ── Nuit, sol, végétation minérale ── */
	.sky {
		fill: color-mix(in srgb, var(--noir-profond) 45%, var(--noir-oki));
		stroke: var(--line);
		stroke-width: 1;
	}

	.star {
		fill: var(--blanc-creme);
		opacity: 0.25;
	}

	.shore {
		fill: var(--gris-sombre);
		opacity: 0.35;
	}

	.ground {
		fill: var(--noir-profond);
		stroke: var(--line);
		stroke-width: 1;
	}

	.plaza {
		fill: rgba(255, 255, 255, 0.04);
		stroke: var(--line);
		stroke-width: 1;
	}

	/* ── Matériaux des bâtiments ── */
	.wall-left {
		fill: color-mix(in srgb, var(--gris-sombre) 60%, var(--noir-oki));
	}

	.wall-right {
		fill: var(--gris-sombre);
	}

	.lamella {
		stroke: rgba(255, 255, 255, 0.06);
		stroke-width: 1;
	}

	.door {
		fill: var(--noir-oki);
	}

	.door-knob {
		fill: var(--or-oki);
		opacity: 0.7;
	}

	.silo-body {
		fill: color-mix(in srgb, var(--gris-sombre) 75%, var(--noir-oki));
	}

	.deck-top {
		fill: var(--gris-sombre);
	}

	.deck-left {
		fill: color-mix(in srgb, var(--gris-sombre) 60%, var(--noir-oki));
	}

	.deck-right {
		fill: color-mix(in srgb, var(--gris-sombre) 80%, var(--noir-oki));
	}

	.post {
		fill: color-mix(in srgb, var(--gris-sombre) 50%, var(--noir-oki));
	}

	.drum {
		fill: color-mix(in srgb, var(--gris-sombre) 55%, var(--noir-oki));
	}

	.drum-top {
		fill: var(--noir-profond);
		stroke: color-mix(in srgb, var(--or-oki) 55%, transparent);
		stroke-width: 1;
	}

	.cloud {
		fill: var(--blanc-creme);
		opacity: 0.15;
	}

	.sign {
		fill: var(--noir-oki);
		stroke: color-mix(in srgb, var(--or-oki) 45%, transparent);
		stroke-width: 1;
	}

	.sign-text {
		font-family: var(--font-display);
		font-size: 12px;
		font-weight: 700;
		letter-spacing: 0.08em;
		fill: var(--blanc-creme);
	}

	.antenna {
		stroke: var(--blanc-creme);
		stroke-width: 2;
		opacity: 0.5;
	}

	.antenna-tick {
		stroke: var(--or-oki);
		stroke-width: 1.5;
		opacity: 0.75;
	}

	.lantern-cord {
		stroke: var(--line);
		stroke-width: 1;
	}

	/* ── Toits : couleurs du drapeau, un accent par bâtiment ── */
	.roof-rouge {
		fill: var(--rouge-oki);
	}

	.roof-rouge-dark {
		fill: color-mix(in srgb, var(--rouge-oki) 55%, var(--noir-oki));
	}

	.roof-vert {
		fill: var(--vert-oki);
	}

	.roof-vert-dark {
		fill: color-mix(in srgb, var(--vert-oki) 55%, var(--noir-oki));
	}

	.roof-or {
		fill: var(--or-oki);
	}

	.roof-line {
		stroke: rgba(0, 0, 0, 0.35);
		stroke-width: 1;
	}

	/* ── Fenêtres lumineuses : scintillement subtil,
	   coupé par la gate reduced-motion globale de base.css ── */
	.win {
		fill: var(--or-clair);
		opacity: 0.82;
		animation: win-glow 4.5s ease-in-out infinite alternate;
	}

	.win-delay {
		animation-delay: -2.2s;
	}

	@keyframes win-glow {
		from {
			opacity: 0.5;
		}
		to {
			opacity: 0.95;
		}
	}

	/* ── Interaction : liseré or + label + léger soulèvement ── */
	.bldg {
		cursor: pointer;
	}

	.bldg-art {
		transition: transform var(--dur-tanbou) var(--ease-ka);
	}

	.bldg:hover .bldg-art,
	.bldg:focus-visible .bldg-art {
		transform: translateY(-5px);
	}

	.bldg-outline {
		fill: none;
		stroke: var(--or-oki);
		stroke-width: 2.5;
		stroke-linejoin: miter;
		opacity: 0;
		transition: opacity var(--dur-tanbou) var(--ease-ka);
	}

	.bldg:hover .bldg-outline,
	.bldg:focus-visible .bldg-outline {
		opacity: 1;
	}

	.bldg-label {
		opacity: 0;
		transition: opacity var(--dur-tanbou) var(--ease-ka);
	}

	.bldg:hover .bldg-label,
	.bldg:focus-visible .bldg-label {
		opacity: 1;
	}

	.label-plaque {
		fill: rgba(13, 13, 13, 0.88);
		stroke: var(--or-oki);
		stroke-width: 1;
	}

	.label-text {
		font-family: var(--font-display);
		font-size: 13px;
		font-weight: 700;
		letter-spacing: 0.05em;
		text-transform: uppercase;
		text-anchor: middle;
		fill: var(--or-oki);
	}

	/* ── Fallback : miroir sémantique, un seul actif à la fois ── */
	.village-fallback {
		display: none;
		list-style: none;
		grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
		gap: var(--space-3);
	}

	.vf-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-2);
		flex-wrap: wrap;
		margin-bottom: var(--space-2);
	}

	.vf-head h3 {
		font-size: 1.1rem;
	}

	.vf-desc {
		color: var(--muted);
		font-size: 0.95rem;
		margin-bottom: var(--space-2);
	}

	.vf-link {
		font-weight: 600;
	}

	@media (prefers-reduced-motion: reduce), (max-width: 640px) {
		.village-scene {
			display: none;
		}

		.village-fallback {
			display: grid;
		}
	}
</style>
