import { forwardRef, lazy, Suspense, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, type CSSProperties, type PointerEvent } from "react";
import { Button, Checker, ColorField, ControlRow, GlassSurface, Icon, IconButton, Inspector, RangeControl, Window } from "@nodedc/ui-react";
import type { MapCameraView, MapGatewayHealth, MapPresentation } from "./CesiumMapRenderer.js";
import sceneFixture from "../../../registry/fixtures/map/map-operational-v0.1.json";

const CesiumMapRenderer = lazy(() => import("./CesiumMapRenderer.js").then((module) => ({ default: module.CesiumMapRenderer })));

type PreviewFeatures = { inspector?: boolean; toolbar?: boolean; assistant?: boolean };
export type MapPageSettings = Omit<MapPresentation, "cacheRefresh">;
type MapRuntimeConfig = { gatewayHealthUrl?: string | null; resourceProxyBase?: string | null };

export type MapPageLayout = {
  schemaVersion: 1;
  pageId: "map";
  settings: MapPageSettings;
  mapHeight: number;
  camera: MapCameraView;
  savedAt?: string;
};

export type MapFixturePreviewHandle = {
  getLayout: () => MapPageLayout | null;
};

const initialMapSettings: MapPageSettings = {
  imagerySource: "cesium-live",
  imageryVisible: true,
  cacheEnabled: true,
  terrainEnabled: true,
  terrainExaggeration: 1,
  monochrome: false,
  monochromeColor: "#15151b",
  imageryGamma: 100,
  imageryHue: 0,
  imageryAlpha: 100,
  globeColor: "#15151b",
  backgroundColor: "#08090d",
  atmosphereEnabled: false,
  atmosphereHue: 0,
  atmosphereSaturation: 0,
  atmosphereBrightness: 0,
  fogEnabled: true,
  fogDensity: 2,
  sunEnabled: true,
  sunHour: 12,
  sunIntensity: 200,
  shadowsEnabled: true,
  buildingsVisible: true,
  buildingsColor: "#a27aff",
  buildingsOpacity: 0.82,
  buildingsDetail: 16,
  imageryBrightness: 100,
  imageryContrast: 100,
  imagerySaturation: 100,
  gridVisible: true,
  gridLodEnabled: true,
  gridHeightMeters: 500,
  gridLod1MaxHeightKm: 10,
  gridLod1StepKm: 1,
  gridLod2MaxHeightKm: 50,
  gridLod2StepKm: 5,
  gridLod3StepKm: 25,
  gridRadiusKm: 40,
  gridLineWidth: 4,
  gridColor: "#f5f5f5",
  gridOpacity: 12,
  gridDotsEnabled: true,
  gridDotsSize: 7,
  gridDotsColor: "#ffffff",
  gridDotsOpacity: 58,
};

// A valid, deterministic scene view is available before Cesium emits its
// first move-end event. It makes the page contract immediately saveable;
// the renderer replaces it with the exact live camera as soon as it is ready.
const fallbackMapCamera: MapCameraView = {
  longitude: sceneFixture.viewport.center[0],
  latitude: sceneFixture.viewport.center[1],
  height: sceneFixture.viewport.range,
  heading: (sceneFixture.viewport.heading * Math.PI) / 180,
  pitch: (sceneFixture.viewport.pitch * Math.PI) / 180,
  roll: 0,
};

export const MapFixturePreview = forwardRef<MapFixturePreviewHandle, {
  features?: PreviewFeatures;
  expanded?: boolean;
  initialLayout?: MapPageLayout | null;
}>(function MapFixturePreview({ features = { inspector: true, toolbar: true, assistant: false }, expanded = false, initialLayout = null }, ref) {
  const selectable = useMemo(() => [
    ...sceneFixture.scene.movingObjects.map((entity) => ({ id: entity.id, title: entity.label.text, kind: entity.objectType, status: entity.status })),
    ...sceneFixture.scene.stations.map((entity) => ({ id: entity.id, title: entity.label.text, kind: `${entity.stationType} station`, status: undefined })),
  ], []);
  const [selectedId, setSelectedId] = useState(sceneFixture.selection.entityId ?? selectable[0]?.id);
  const [inspectorOpen, setInspectorOpen] = useState(false);
  const [layersOpen, setLayersOpen] = useState(false);
  const [toolbarOpen, setToolbarOpen] = useState(Boolean(features.toolbar));
  const [assistantOpen, setAssistantOpen] = useState(false);
  const [mapSettings, setMapSettings] = useState<MapPageSettings>(() => ({ ...initialMapSettings, ...initialLayout?.settings }));
  const [mapHeight, setMapHeight] = useState(() => initialLayout?.mapHeight ?? (expanded ? 620 : 470));
  const [mapCamera, setMapCamera] = useState<MapCameraView>(initialLayout?.camera ?? fallbackMapCamera);
  // The header Save action can be pressed immediately after Cesium finishes
  // constructing the scene. Keep the last camera synchronously as well as in
  // state, so the imperative page-layout contract never waits for React's
  // render cycle to publish a ready camera.
  const mapCameraRef = useRef<MapCameraView>(initialLayout?.camera ?? fallbackMapCamera);
  const [rendererRevision, setRendererRevision] = useState(0);
  const [gatewayHealth, setGatewayHealth] = useState<MapGatewayHealth | null>(null);
  const [gatewayEndpoint, setGatewayEndpoint] = useState<string | null>(null);
  const [gatewayCheckState, setGatewayCheckState] = useState<"idle" | "checking" | "ready" | "error">("idle");
  const [gatewayCheckError, setGatewayCheckError] = useState<string | null>(null);
  const selected = selectable.find((entity) => entity.id === selectedId) ?? selectable[0];
  const presentation: MapPresentation = { ...mapSettings, cacheRefresh: false };
  const updateMapSettings = (patch: Partial<MapPageSettings>) => setMapSettings((current) => ({ ...current, ...patch }));
  const setCacheEnabled = (cacheEnabled: boolean) => {
    updateMapSettings({ cacheEnabled });
    setRendererRevision((value) => value + 1);
  };

  const handleCameraChange = useCallback((camera: MapCameraView) => {
    mapCameraRef.current = camera;
    setMapCamera(camera);
  }, []);

  useImperativeHandle(ref, () => ({
    getLayout: () => ({
      schemaVersion: 1,
      pageId: "map",
      settings: mapSettings,
      mapHeight: Math.round(mapHeight),
      camera: mapCameraRef.current ?? mapCamera,
    }),
  }), [mapCamera, mapHeight, mapSettings]);

  const handleSelect = useCallback((entityId: string) => {
    if (!selectable.some((entity) => entity.id === entityId)) return;
    setSelectedId(entityId);
  }, [selectable]);

  const verifyGateway = useCallback(async () => {
    setGatewayCheckState("checking");
    setGatewayCheckError(null);
    try {
      const runtimeResponse = await fetch("/api/map/runtime-config");
      const runtime = runtimeResponse.ok ? await runtimeResponse.json() as MapRuntimeConfig : null;
      if (!runtime?.gatewayHealthUrl) throw new Error("gateway_not_configured");
      const healthResponse = await fetch(runtime.gatewayHealthUrl);
      if (!healthResponse.ok) throw new Error("gateway_not_ready");
      const health = await healthResponse.json() as MapGatewayHealth;
      if (health.cache?.persistent !== true) throw new Error("persistent_cache_unavailable");
      setGatewayHealth(health);
      setGatewayEndpoint(new URL(runtime.gatewayHealthUrl).origin);
      setGatewayCheckState("ready");
    } catch (error) {
      const code = error instanceof Error ? error.message : "gateway_not_ready";
      setGatewayHealth(null);
      setGatewayEndpoint(null);
      setGatewayCheckError(code === "persistent_cache_unavailable"
        ? "Persistent TileCache не подключён: карта не должна продолжать работу с локальной временной папкой."
        : "Platform Map Gateway недоступен: проверьте runtime profile и persistent volume.");
      setGatewayCheckState("error");
    }
  }, []);

  useEffect(() => {
    if (!inspectorOpen && !layersOpen) return;
    void verifyGateway();
    const interval = window.setInterval(() => void verifyGateway(), 5000);
    return () => window.clearInterval(interval);
  }, [inspectorOpen, layersOpen, verifyGateway]);

  const liveCacheStatus = gatewayHealth?.cache;
  const liveCacheSummary = liveCacheStatus
    ? `${liveCacheStatus.entries ?? 0} объектов · ${Math.round((liveCacheStatus.bytes ?? 0) / 1024 / 1024)} MB`
    : "индекс ещё не получен";

  const startResize = (event: PointerEvent<HTMLButtonElement>) => {
    event.preventDefault();
    const startY = event.clientY;
    const startHeight = mapHeight;
    const onMove = (move: globalThis.PointerEvent) => {
      const maximum = Math.max(380, Math.round(window.innerHeight * 0.78));
      setMapHeight(Math.max(360, Math.min(maximum, startHeight + move.clientY - startY)));
    };
    const onEnd = () => {
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onEnd);
      window.removeEventListener("pointercancel", onEnd);
    };
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onEnd);
    window.addEventListener("pointercancel", onEnd);
  };

  const inspectorSections = [
    {
      id: "map-base",
      label: "Подложка и terrain",
      description: "provider-neutral surface",
      group: "Карта",
      content: <>
        <ControlRow label="Подложка"><strong>Cesium World Imagery</strong></ControlRow>
        <small className="catalog-map-inspector__note">Текущий официальный provider. Другие provider-слои появятся только после отдельного asset-контракта Platform.</small>
        <Checker checked={mapSettings.terrainEnabled} label="Terrain" description="Рельеф — отдельный слой под imagery." onChange={(terrainEnabled) => updateMapSettings({ terrainEnabled })} />
        <RangeControl label="Вертикальное преувеличение рельефа" value={mapSettings.terrainExaggeration * 100} min={25} max={300} formatValue={(value) => `${(value / 100).toFixed(2)}×`} onChange={(value) => updateMapSettings({ terrainExaggeration: value / 100 })} />
        <Checker checked={mapSettings.monochrome} label="Монохромная поверхность" onChange={(monochrome) => updateMapSettings({ monochrome })} />
        <ControlRow label="Цвет монохрома"><ColorField label="Цвет монохромной поверхности" value={mapSettings.monochromeColor} onChange={(monochromeColor) => updateMapSettings({ monochromeColor })} /></ControlRow>
        <RangeControl label="Яркость" value={mapSettings.imageryBrightness} min={0} max={200} formatValue={(value) => `${value}%`} onChange={(imageryBrightness) => updateMapSettings({ imageryBrightness })} />
        <RangeControl label="Контраст" value={mapSettings.imageryContrast} min={0} max={200} formatValue={(value) => `${value}%`} onChange={(imageryContrast) => updateMapSettings({ imageryContrast })} />
        <RangeControl label="Насыщенность" value={mapSettings.imagerySaturation} min={0} max={200} formatValue={(value) => `${value}%`} onChange={(imagerySaturation) => updateMapSettings({ imagerySaturation })} />
        <RangeControl label="Гамма" value={mapSettings.imageryGamma} min={0} max={300} formatValue={(value) => `${value}%`} onChange={(imageryGamma) => updateMapSettings({ imageryGamma })} />
        <RangeControl label="Оттенок" value={mapSettings.imageryHue} min={-180} max={180} formatValue={(value) => `${value}°`} onChange={(imageryHue) => updateMapSettings({ imageryHue })} />
        <RangeControl label="Прозрачность imagery" value={mapSettings.imageryAlpha} min={0} max={100} formatValue={(value) => `${value}%`} onChange={(imageryAlpha) => updateMapSettings({ imageryAlpha })} />
        <ControlRow label="Цвет планеты"><ColorField label="Цвет terrain без imagery" value={mapSettings.globeColor} onChange={(globeColor) => updateMapSettings({ globeColor })} /></ControlRow>
        <ControlRow label="Фон сцены"><ColorField label="Цвет фона сцены" value={mapSettings.backgroundColor} onChange={(backgroundColor) => updateMapSettings({ backgroundColor })} /></ControlRow>
      </>,
    },
    {
      id: "map-atmosphere",
      label: "Атмосфера и освещение",
      description: "scene / color correction",
      group: "Карта",
      content: <>
        <Checker checked={mapSettings.atmosphereEnabled} label="Показывать атмосферу" onChange={(atmosphereEnabled) => updateMapSettings({ atmosphereEnabled })} />
        <RangeControl label="Атмосфера: оттенок" value={mapSettings.atmosphereHue} min={-100} max={100} formatValue={(value) => `${value}%`} onChange={(atmosphereHue) => updateMapSettings({ atmosphereHue })} />
        <RangeControl label="Атмосфера: насыщенность" value={mapSettings.atmosphereSaturation} min={-100} max={100} formatValue={(value) => `${value}%`} onChange={(atmosphereSaturation) => updateMapSettings({ atmosphereSaturation })} />
        <RangeControl label="Атмосфера: яркость" value={mapSettings.atmosphereBrightness} min={-100} max={100} formatValue={(value) => `${value}%`} onChange={(atmosphereBrightness) => updateMapSettings({ atmosphereBrightness })} />
        <Checker checked={mapSettings.fogEnabled} label="Туман" onChange={(fogEnabled) => updateMapSettings({ fogEnabled })} />
        <RangeControl label="Плотность тумана" value={mapSettings.fogDensity} min={0} max={100} formatValue={(value) => `${(value / 10000).toFixed(4)}`} onChange={(fogDensity) => updateMapSettings({ fogDensity })} />
        <Checker checked={mapSettings.sunEnabled} label="Солнечное освещение" onChange={(sunEnabled) => updateMapSettings({ sunEnabled })} />
        <RangeControl label="Час солнца" value={mapSettings.sunHour} min={0} max={24} formatValue={(value) => `${value}:00 UTC`} onChange={(sunHour) => updateMapSettings({ sunHour })} />
        <RangeControl label="Интенсивность света" value={mapSettings.sunIntensity} min={0} max={200} formatValue={(value) => `${value}%`} onChange={(sunIntensity) => updateMapSettings({ sunIntensity })} />
        <Checker checked={mapSettings.shadowsEnabled} label="Тени" onChange={(shadowsEnabled) => updateMapSettings({ shadowsEnabled })} />
      </>,
    },
    {
      id: "map-buildings",
      label: "3D здания",
      description: "3D Tiles / detail",
      group: "Карта",
      content: <>
        <Checker checked={mapSettings.buildingsVisible} label="Показывать 3D здания" onChange={(buildingsVisible) => updateMapSettings({ buildingsVisible })} />
        <ControlRow label="Цвет"><ColorField label="Цвет зданий" value={mapSettings.buildingsColor} onChange={(buildingsColor) => updateMapSettings({ buildingsColor })} /></ControlRow>
        <RangeControl label="Прозрачность" value={Math.round(mapSettings.buildingsOpacity * 100)} min={0} max={100} formatValue={(value) => `${value}%`} onChange={(value) => updateMapSettings({ buildingsOpacity: value / 100 })} />
        <RangeControl label="Детализация" value={mapSettings.buildingsDetail} min={4} max={32} formatValue={(value) => `SSE ${value}`} onChange={(buildingsDetail) => updateMapSettings({ buildingsDetail })} />
      </>,
    },
    {
      id: "map-grid",
      label: "Сетка и LOD",
      description: "first adapter control",
      group: "Слои",
      content: <>
        <Checker checked={mapSettings.gridVisible} label="3D-сетка" description="Сетка размещается над поверхностью и меняет шаг по высоте камеры." onChange={(gridVisible) => updateMapSettings({ gridVisible })} />
        <Checker checked={mapSettings.gridLodEnabled} label="LOD по высоте камеры" onChange={(gridLodEnabled) => updateMapSettings({ gridLodEnabled })} />
        <RangeControl label="Высота над поверхностью" value={mapSettings.gridHeightMeters} min={0} max={1000} formatValue={(value) => `${value} м`} onChange={(gridHeightMeters) => updateMapSettings({ gridHeightMeters })} />
        <RangeControl label="LOD 1: до высоты" value={mapSettings.gridLod1MaxHeightKm} min={1} max={50} formatValue={(value) => `${value} км`} onChange={(gridLod1MaxHeightKm) => updateMapSettings({ gridLod1MaxHeightKm })} />
        <RangeControl label="LOD 1: шаг" value={mapSettings.gridLod1StepKm} min={1} max={10} formatValue={(value) => `${value} км`} onChange={(gridLod1StepKm) => updateMapSettings({ gridLod1StepKm })} />
        <RangeControl label="LOD 2: до высоты" value={mapSettings.gridLod2MaxHeightKm} min={10} max={200} formatValue={(value) => `${value} км`} onChange={(gridLod2MaxHeightKm) => updateMapSettings({ gridLod2MaxHeightKm })} />
        <RangeControl label="LOD 2: шаг" value={mapSettings.gridLod2StepKm} min={1} max={25} formatValue={(value) => `${value} км`} onChange={(gridLod2StepKm) => updateMapSettings({ gridLod2StepKm })} />
        <RangeControl label="LOD 3: шаг" value={mapSettings.gridLod3StepKm} min={5} max={100} formatValue={(value) => `${value} км`} onChange={(gridLod3StepKm) => updateMapSettings({ gridLod3StepKm })} />
        <RangeControl label="Радиус сетки" value={mapSettings.gridRadiusKm} min={5} max={150} formatValue={(value) => `${value} км`} onChange={(gridRadiusKm) => updateMapSettings({ gridRadiusKm })} />
        <ControlRow label="Цвет линий"><ColorField label="Цвет линий сетки" value={mapSettings.gridColor} onChange={(gridColor) => updateMapSettings({ gridColor })} /></ControlRow>
        <RangeControl label="Толщина линий" value={mapSettings.gridLineWidth} min={1} max={8} formatValue={(value) => `${value} px`} onChange={(gridLineWidth) => updateMapSettings({ gridLineWidth })} />
        <RangeControl label="Прозрачность сетки" value={mapSettings.gridOpacity} min={0} max={100} formatValue={(value) => `${value}%`} onChange={(gridOpacity) => updateMapSettings({ gridOpacity })} />
        <Checker checked={mapSettings.gridDotsEnabled} label="Точки в пересечениях" onChange={(gridDotsEnabled) => updateMapSettings({ gridDotsEnabled })} />
        <RangeControl label="Размер точки" value={mapSettings.gridDotsSize} min={2} max={28} formatValue={(value) => `${value} px`} onChange={(gridDotsSize) => updateMapSettings({ gridDotsSize })} />
        <ControlRow label="Цвет точек"><ColorField label="Цвет точек сетки" value={mapSettings.gridDotsColor} onChange={(gridDotsColor) => updateMapSettings({ gridDotsColor })} /></ControlRow>
        <RangeControl label="Прозрачность точек" value={mapSettings.gridDotsOpacity} min={0} max={100} formatValue={(value) => `${value}%`} onChange={(gridDotsOpacity) => updateMapSettings({ gridDotsOpacity })} />
      </>,
    },
    {
      id: "map-cache",
      label: "TileCache",
      description: "Platform Map Gateway",
      group: "Хранение",
      content: <>
        <small className="catalog-map-inspector__note">По умолчанию — официальный live-маршрут. Включите запись, чтобы одновременно смотреть карту и пополнять серверный cache.</small>
        <Checker className="catalog-map-inspector__cache-toggle" checked={mapSettings.cacheEnabled} label="Кэшировать live-данные" onChange={setCacheEnabled} />
        <ControlRow label="Режим"><strong>{mapSettings.cacheEnabled ? "Live + Cache" : "Live"}</strong></ControlRow>
        <ControlRow label="Хранилище"><strong>Platform Map Gateway</strong></ControlRow>
        <ControlRow label="Подключение"><span>{gatewayEndpoint ?? "runtime profile · не проверено"}</span></ControlRow>
        <ControlRow label="Записано"><strong>{liveCacheSummary}</strong></ControlRow>
        <Button variant="secondary" shape="pill" icon={<Icon name="refresh" />} onClick={() => void verifyGateway()} disabled={gatewayCheckState === "checking"}>{gatewayCheckState === "checking" ? "Проверяем Gateway…" : "Проверить подключение"}</Button>
        <small className="catalog-map-inspector__note">Live Cache: {liveCacheSummary} · {gatewayHealth?.cache?.mode ?? "проверяется"}</small>
        <small className="catalog-map-inspector__note">{mapSettings.cacheEnabled ? "Hybrid: provider остаётся официальным, новые tiles сохраняются в серверный cache." : "Real-time: provider остаётся официальным, чтение и запись persistent cache выключены."}</small>
        {gatewayCheckState === "error" ? <small className="catalog-map-inspector__note catalog-map-inspector__note--error" role="alert">{gatewayCheckError}</small> : null}
      </>,
    },
    {
      id: "map-selection",
      label: "Выбранная сущность",
      description: "selection contract",
      group: "Данные",
      content: <>
        <ControlRow label="Сущность"><strong>{selected?.title ?? "Нет выбора"}</strong></ControlRow>
        <ControlRow label="Тип"><span>{selected?.kind ?? "—"}{selected?.status ? ` · ${selected.status}` : ""}</span></ControlRow>
      </>,
    },
  ];

  return (
    <div
      className={`catalog-map-fixture${expanded ? " catalog-map-fixture--expanded" : ""}`}
      style={{ "--catalog-map-height": `${mapHeight}px` } as CSSProperties}
      aria-label="Map Page Cesium adapter"
    >
      <Suspense fallback={<div className="catalog-map-fixture__loading">Загрузка карты…</div>}>
        <CesiumMapRenderer key={rendererRevision} onSelect={handleSelect} onGatewayHealth={setGatewayHealth} onCameraChange={handleCameraChange} initialCamera={mapCamera ?? undefined} presentation={presentation} />
      </Suspense>

      <div className="catalog-map-fixture__actions">
        <IconButton label="Настройки карты" aria-pressed={inspectorOpen} data-active={inspectorOpen || undefined} onClick={() => setInspectorOpen(true)}><Icon name="settings" /></IconButton>
        <IconButton label="Слои карты" aria-pressed={layersOpen} data-active={layersOpen || undefined} onClick={() => setLayersOpen((value) => !value)}><Icon name="grid" /></IconButton>
        {features.toolbar ? <IconButton label="Toolbar" aria-pressed={toolbarOpen} data-active={toolbarOpen || undefined} onClick={() => setToolbarOpen((value) => !value)}><Icon name="panel" /></IconButton> : null}
        {features.assistant ? <IconButton label="Assistant" aria-pressed={assistantOpen} data-active={assistantOpen || undefined} onClick={() => setAssistantOpen((value) => !value)}><Icon name="apps" /></IconButton> : null}
      </div>

      {layersOpen ? (
        <GlassSurface className="catalog-map-fixture__layers" tone="strong" radius="card" padding="sm" aria-label="Настройки слоёв карты">
          <div className="catalog-map-fixture__layers-head"><strong>Слои карты</strong><IconButton label="Закрыть слои" onClick={() => setLayersOpen(false)}><Icon name="close" /></IconButton></div>
          <div className="catalog-map-fixture__provider"><strong>Cesium World Imagery</strong><small>официальный live provider</small></div>
          <Checker checked={mapSettings.terrainEnabled} label="Terrain" onChange={(terrainEnabled) => updateMapSettings({ terrainEnabled })} />
          <Checker checked={mapSettings.buildingsVisible} label="3D здания" onChange={(buildingsVisible) => updateMapSettings({ buildingsVisible })} />
          <Checker checked={mapSettings.gridVisible} label="Планетарная сетка" onChange={(gridVisible) => updateMapSettings({ gridVisible })} />
          <small className="catalog-map-inspector__note">Live Cache: {liveCacheSummary}</small>
          <Checker className="catalog-map-fixture__cache-toggle" checked={mapSettings.cacheEnabled} label="Кэшировать live-данные" onChange={setCacheEnabled} />
        </GlassSurface>
      ) : null}

      {toolbarOpen ? (
        <div className="catalog-map-fixture__toolbar" aria-label="Map toolbar">
          <IconButton label="Обзор"><Icon name="globe" /></IconButton>
          <IconButton label="Поиск"><Icon name="search" /></IconButton>
        </div>
      ) : null}

      {assistantOpen ? <div className="catalog-map-fixture__assistant"><strong>NODE.DC Assistant</strong><span>Контекст выбранной сущности готов к передаче.</span></div> : null}
      <button type="button" className="catalog-map-fixture__resize" aria-label="Изменить высоту карты" onPointerDown={startResize}><span /></button>

      <Window
        open={inspectorOpen && Boolean(features.inspector)}
        title="Настройки карты"
        subtitle="MAP / draggable inspector"
        placement="end"
        draggable
        closeOnBackdrop={false}
        lockBodyScroll={false}
        trapFocus={false}
        onClose={() => setInspectorOpen(false)}
      >
        <Inspector sections={inspectorSections} defaultOpen={["map-base"]} singleOpen />
      </Window>
    </div>
  );
});
