'use client';
import dynamic from 'next/dynamic';
import { useMemo, useState } from 'react';
import { LevelLegend } from '@/components/ui/primitives';
import { useLive } from '@/lib/live';
import type { Country, Front, Incident, LatencyPair, Probe, Region } from '@/lib/types';
import { ModeSelector } from './ModeSelector';
import { type MapMode } from './modes';
const WorldMap = dynamic(() => import('./WorldMap').then((m) => m.WorldMap), {
ssr: false,
loading: () =>
Loading map…
,
});
export interface MapData {
regions: Region[] | null;
countries: Country[] | null;
probes: Probe[] | null;
fronts: Front[] | null;
incidents: Incident[] | null;
matrix: LatencyPair[] | null;
}
/** Client island: the map itself is lazy-loaded (no SSR); live slices override the SSR data. */
export function MapIsland({ initial, height = 'h-[300px] sm:h-[420px] lg:h-[520px]', initialMode = 'pressure' }: { initial: MapData; height?: string; initialMode?: MapMode }) {
const [mode, setMode] = useState(initialMode);
const liveRegions = useLive((s) => s.regions);
const liveFronts = useLive((s) => s.fronts);
const liveIncidents = useLive((s) => s.incidents);
const liveCountries = useLive((s) => s.countries);
// Memoised so the map's data effect only re-runs when a real regional update arrived.
const countries = useMemo(() => {
if (!initial.countries) return null;
if (!liveCountries) return initial.countries;
const byCc = new Map(liveCountries.map((x) => [x.cc, x]));
return initial.countries.map((c) => {
const u = byCc.get(c.cc);
return u ? { ...c, pressure: u.pressure, level: u.level, delta_1h: u.delta_1h } : c;
});
}, [initial.countries, liveCountries]);
return (
{mode === 'probes' ? 'Arc thickness = |z| of the inter-region latency matrix' : mode === 'incidents' ? 'Markers = incidents with a geographic scope' : 'Countries coloured only where we hold measurements'}
);
}