/* Kaart screen: MapLibre + Centric toolbar + right layers panel */

const LAGEN_CONFIG = [
  { id:'woonplaatsen',     label:'Woonplaatsen',      swatch:'#004494', mapLayers:['woonplaatsen-outline'],          sourceId:'woonplaatsen',             hasOpacity:true,  paintFn:(map,op)=>{ try{map.setPaintProperty('woonplaatsen-outline','line-opacity',op);}catch(e){} } },
  { id:'panden',           label:'Panden',             swatch:'#3b82f6', mapLayers:['panden-fill','panden-outline'],  sourceId:'panden',                   hasOpacity:true,  paintFn:(map,op)=>{ try{map.setPaintProperty('panden-fill','fill-opacity',op*0.65);}catch(e){} } },
  { id:'percelen',         label:'Percelen',           swatch:'#f97316', mapLayers:['percelen-wmts','percelen-wfs','percelen-fill'],  sourceId:'percelen-wfs',             hasOpacity:true,  paintFn:(map,op)=>{ try{map.setPaintProperty('percelen-wmts','raster-opacity',op);}catch(e){} } },
  { id:'zonnepanelen',     label:'Zonnepanelen',       swatch:'#eab308', mapLayers:['resultaten-zonnepanelen-fill','resultaten-zonnepanelen-line'],       sourceId:'resultaten-zonnepanelen',  hasOpacity:true,  paintFn:(map,op)=>{ try{map.setPaintProperty('resultaten-zonnepanelen-fill','fill-opacity',op*0.4);map.setPaintProperty('resultaten-zonnepanelen-line','line-opacity',op);}catch(e){} } },
  { id:'dakkapellen',      label:'Dakkapellen',        swatch:'#8b5cf6', mapLayers:['resultaten-dakkapellen-fill','resultaten-dakkapellen-line'],        sourceId:'resultaten-dakkapellen',   hasOpacity:true,  paintFn:(map,op)=>{ try{map.setPaintProperty('resultaten-dakkapellen-fill','fill-opacity',op*0.4);map.setPaintProperty('resultaten-dakkapellen-line','line-opacity',op);}catch(e){} } },
  { id:'contourafwijking', label:'Contourafwijking',   swatch:'#ef4444', mapLayers:['resultaten-contourafwijking-fill','resultaten-contourafwijking-line'],   sourceId:'resultaten-contourafwijking', hasOpacity:true, paintFn:(map,op)=>{ try{map.setPaintProperty('resultaten-contourafwijking-fill','fill-opacity',op*0.4);map.setPaintProperty('resultaten-contourafwijking-line','line-opacity',op);}catch(e){} } },
  { id:'perceel-objecten', label:'Perceel-objecten',   swatch:'#06b6d4', mapLayers:['perceel-objecten-fill','perceel-objecten-line'], sourceId:'perceel-objecten', hasOpacity:true, paintFn:(map,op)=>{ try{map.setPaintProperty('perceel-objecten-fill','fill-opacity',op*0.35);map.setPaintProperty('perceel-objecten-line','line-opacity',op);}catch(e){} } },
];

function boundsVanSource(map, sourceId) {
  const src = map.getSource(sourceId);
  if (!src) return null;
  const data = src._data;
  if (!data?.features?.length) return null;
  const bounds = new maplibregl.LngLatBounds();
  data.features.forEach(f => {
    if (!f.geometry) return;
    const flat = (coords) => {
      if (!coords?.length) return;
      if (typeof coords[0] === 'number') { bounds.extend(coords); return; }
      coords.forEach(flat);
    };
    flat(f.geometry.coordinates);
  });
  return bounds.isEmpty() ? null : bounds;
}

function BboxKopieerKnop({ waarde }) {
  const [gekopieerd, setGekopieerd] = useState(false);
  function kopieer() {
    navigator.clipboard.writeText(waarde).then(() => {
      setGekopieerd(true);
      setTimeout(() => setGekopieerd(false), 1500);
    });
  }
  return (
    <button onClick={kopieer} className="bd-tool-btn" style={{width:22, height:22}} title="Kopieer bounding box">
      <Icon name={gekopieerd ? 'check' : 'copy'} size={12} style={{color: gekopieerd ? 'var(--color-success)' : undefined}} />
    </button>
  );
}

function LaagRij({ laag, laagInstellingen, laagInstellingenRef, setLaagInstellingen, mapInstanceRef, laadPercelen, onDragStart, onDragOver, onDrop, isDragOver }) {
  const inst = laagInstellingen[laag.id];
  const aan = inst.aan;
  const [expanded, setExpanded] = useState(false);

  function toggleLaag() {
    const nieuw = !aan;
    const volgende = {...laagInstellingenRef.current, [laag.id]: {...laagInstellingenRef.current[laag.id], aan: nieuw}};
    laagInstellingenRef.current = volgende;
    setLaagInstellingen(volgende);
    const map = mapInstanceRef.current;
    if (!map) return;
    laag.mapLayers.forEach(lid => { try { map.setLayoutProperty(lid, 'visibility', nieuw ? 'visible' : 'none'); } catch(e) {} });
    if (laag.id === 'percelen' && nieuw) laadPercelen();
  }

  function stapOpacity(delta) {
    const huidig = Math.round(laagInstellingenRef.current[laag.id].opacity * 10) * 10;
    const nieuw = Math.min(100, Math.max(10, huidig + delta)) / 100;
    const volgende = {...laagInstellingenRef.current, [laag.id]: {...laagInstellingenRef.current[laag.id], opacity: nieuw}};
    laagInstellingenRef.current = volgende;
    setLaagInstellingen(volgende);
    const map = mapInstanceRef.current;
    if (map && laag.paintFn) laag.paintFn(map, nieuw);
  }

  const opPct = Math.round((inst.opacity || 1) * 10) * 10;

  return (
    <div className={'bd-layer-item' + (isDragOver ? ' drag-over' : '')}
      draggable
      onDragStart={e => { e.dataTransfer.effectAllowed = 'move'; onDragStart(laag.id); }}
      onDragOver={e => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; onDragOver(laag.id); }}
      onDrop={e => { e.preventDefault(); onDrop(laag.id); }}
      onDragEnd={() => onDrop(null)}>
      <div className="bd-layer-row">
        <span className="bd-layer-drag" style={{cursor:'grab'}}><Icon name="grip-vertical" size={11} /></span>
        <span className={'bd-layer-chevron' + (laag.hasOpacity ? (expanded ? ' is-open' : '') : ' is-hidden')}
          onClick={e => { e.stopPropagation(); setExpanded(v => !v); }}>
          <Icon name="chevron-right" size={9} />
        </span>
        <span className={'bd-layer-check' + (aan ? ' is-on' : '')} onClick={toggleLaag}>
          {aan && <Icon name="check" size={9} style={{color:'#fff', strokeWidth:3}} />}
        </span>
        <span className="bd-layer-swatch" style={{background: laag.swatch}} />
        <span className={'bd-layer-name' + (aan ? '' : ' is-off')} onClick={toggleLaag}>{laag.label}</span>
        {laag.sourceId && (
          <button className="bd-layer-zoom-btn" title="Zoom naar laag"
            onClick={e => {
              e.stopPropagation();
              const map = mapInstanceRef.current;
              if (!map) return;
              const b = boundsVanSource(map, laag.sourceId);
              if (b) map.fitBounds(b, { padding: 60, animate: true });
            }}>
            <Icon name="maximize-2" size={10} />
          </button>
        )}
      </div>
      {expanded && laag.hasOpacity && (
        <div className="bd-layer-expand">
          <div className="bd-layer-opacity">
            <span className="bd-layer-opacity-label">Helderheid</span>
            <button className="bd-layer-opacity-btn" onClick={() => stapOpacity(-10)}>◄</button>
            <div className="bd-layer-opacity-track"><div className="bd-layer-opacity-fill" style={{width: opPct + '%'}} /></div>
            <button className="bd-layer-opacity-btn" onClick={() => stapOpacity(10)}>►</button>
            <span className="bd-layer-opacity-val">{opPct}%</span>
          </div>
        </div>
      )}
    </div>
  );
}

function KopieerKnop({ tekst, label }) {
  const [gekopieerd, setGekopieerd] = useState(false);
  function kopieer() {
    navigator.clipboard.writeText(tekst)
      .then(() => { setGekopieerd(true); setTimeout(() => setGekopieerd(false), 1500); })
      .catch(() => {});
  }
  return (
    <Btn kind="secondary" size="sm" icon={gekopieerd ? 'check' : 'copy'} onClick={kopieer}>
      {gekopieerd ? 'Gekopieerd!' : label}
    </Btn>
  );
}

/* Ray-casting point-in-polygon op schermcoördinaten. poly = [{x,y},...]. */
function puntInPolygoon(x, y, poly) {
  let inside = false;
  for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
    const xi = poly[i].x, yi = poly[i].y, xj = poly[j].x, yj = poly[j].y;
    if (((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) inside = !inside;
  }
  return inside;
}

/* Simpele centroid (gemiddelde van de buitenring) in lng/lat van een (Multi)Polygon. */
function geomCentroidLngLat(geom) {
  if (!geom) return null;
  let ring = null;
  if (geom.type === 'Polygon') ring = geom.coordinates[0];
  else if (geom.type === 'MultiPolygon') ring = geom.coordinates[0] && geom.coordinates[0][0];
  if (!ring || !ring.length) return null;
  let sx = 0, sy = 0;
  for (const c of ring) { sx += c[0]; sy += c[1]; }
  return [sx / ring.length, sy / ring.length];
}

function SelectieOverlay({ mode, tekenPunten, startPunt, muisPunt, snapActief }) {
  if (mode === 'navigeren') return null;

  const blauw = '#004494';
  const dashArray = '5,4';

  if (mode === 'rechthoek' && startPunt && muisPunt) {
    const x = Math.min(startPunt.x, muisPunt.x);
    const y = Math.min(startPunt.y, muisPunt.y);
    const w = Math.abs(muisPunt.x - startPunt.x);
    const h = Math.abs(muisPunt.y - startPunt.y);
    return (
      <svg style={{position:'absolute',inset:0,width:'100%',height:'100%',pointerEvents:'none',zIndex:10}}>
        <rect x={x} y={y} width={w} height={h}
          fill={blauw} fillOpacity={0.1}
          stroke={blauw} strokeWidth={1.5} strokeDasharray={dashArray} />
        <circle cx={startPunt.x} cy={startPunt.y} r={4} fill="white" stroke={blauw} strokeWidth={1.5} />
      </svg>
    );
  }

  if (mode === 'polygoon' && tekenPunten.length > 0) {
    const punten = [...tekenPunten, muisPunt].filter(Boolean);
    const polyline = punten.map((p,i) => `${i===0?'M':'L'}${p.x},${p.y}`).join(' ');
    return (
      <svg style={{position:'absolute',inset:0,width:'100%',height:'100%',pointerEvents:'none',zIndex:10}}>
        <path d={polyline} fill="none" stroke={blauw} strokeWidth={1.5} strokeDasharray={dashArray} />
        {tekenPunten.map((p,i) => (
          <circle key={i} cx={p.x} cy={p.y} r={4} fill="white" stroke={blauw} strokeWidth={1.5} />
        ))}
        {snapActief && tekenPunten.length > 0 && (
          <circle cx={tekenPunten[0].x} cy={tekenPunten[0].y} r={8}
            fill="none" stroke="#22c55e" strokeWidth={2} />
        )}
      </svg>
    );
  }

  return null;
}

function SchermKaart({ gemeenten, kaartmateriaal, defaultGemeente, onNaarPand }) {
  const [geselecteerdeGemeente, setGeselecteerdeGemeente] = useState(() => defaultGemeente || '');
  const [zoekterm, setZoekterm] = useState('');
  const [suggesties, setSuggesties] = useState([]);
  const [detailPand, setDetailPand] = useState(null);
  const [lagenPanelOpen, setLagenPanelOpen] = useState(true);
  const [laagInstellingen, setLaagInstellingen] = useState({
    woonplaatsen:     { aan: true,  opacity: 0.8  },
    panden:           { aan: true,  opacity: 0.65 },
    zonnepanelen:     { aan: false, opacity: 1.0  },
    dakkapellen:      { aan: false, opacity: 1.0  },
    contourafwijking: { aan: false, opacity: 1.0  },
    'perceel-objecten': { aan: false, opacity: 1.0 },
    percelen:         { aan: false, opacity: 0.8  },
  });
  const [achtergrondId, setAchtergrondId] = useState(null);
  const [lagenVolgorde, setLagenVolgorde] = useState(() => LAGEN_CONFIG.map(l => l.id));
  const [dragBron, setDragBron] = useState(null);
  const [dragDoel, setDragDoel] = useState(null);
  const [geselecteerdPandId, setGeselecteerdPandId] = React.useState(null);
  const [nietAanwezigZichtbaar, setNietAanwezigZichtbaar] = React.useState(false);
  const [inactiefZichtbaar, setInactiefZichtbaar] = React.useState(false);
  const [bbox, setBbox] = useState(null);
  const [activeTool, setActiveTool] = useState('navigeren');
  const [geselecteerdePanden, setGeselecteerdePanden] = useState([]);
  const [geselecteerdePercelen, setGeselecteerdePercelen] = useState([]);
  const [vanuitSelectie, setVanuitSelectie] = useState(false);
  const activeToolRef = useRef('navigeren');
  useEffect(() => { activeToolRef.current = activeTool; }, [activeTool]);
  const [tekenPunten, setTekenPunten] = useState([]);
  const [startPunt, setStartPunt] = useState(null);
  const [muisPunt, setMuisPunt] = useState(null);
  const [snapActief, setSnapActief] = useState(false);
  const tekenPuntenRef = useRef([]);
  const startPuntRef = useRef(null);
  useEffect(() => { tekenPuntenRef.current = tekenPunten; }, [tekenPunten]);
  useEffect(() => { startPuntRef.current = startPunt; }, [startPunt]);
  const [panelBreedte, setPanelBreedte] = useState(250);
  const mapRef = useRef(null);
  const mapInstanceRef = useRef(null);
  const gemRef = useRef(geselecteerdeGemeente);
  const laagInstellingenRef = useRef(laagInstellingen);

  function openPandDetailInData(pandId) {
    if (!pandId || !onNaarPand) return;
    onNaarPand(pandId);
  }

  useEffect(() => { gemRef.current = geselecteerdeGemeente; }, [geselecteerdeGemeente]);
  useEffect(() => { laagInstellingenRef.current = laagInstellingen; }, [laagInstellingen]);
  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map) return;
    if (activeTool === 'navigeren') {
      map.dragPan.enable();
      map.getCanvas().style.cursor = '';
      setSnapActief(false);
      setTekenPunten([]);
      setStartPunt(null);
      setMuisPunt(null);
    } else {
      map.dragPan.disable();
      map.getCanvas().style.cursor = 'crosshair';
      setSnapActief(false);
      setTekenPunten([]);
      setStartPunt(null);
      setMuisPunt(null);
    }
  }, [activeTool]);

  useEffect(() => {
    if (mapInstanceRef.current) return;
    const map = new maplibregl.Map({
      container: mapRef.current,
      style: { version: 8, sources: {}, layers: [], glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf' },
      center: [5.2913, 52.1326], zoom: 10,
    });
    map.on('load', () => {
      // Achtergrondtile
      map.addSource('brt', { type: 'raster', tiles: [BRT_WMTS_TEMPLATE], tileSize: 256 });
      map.addLayer({ id: 'brt', type: 'raster', source: 'brt' });

      // Woonplaatsgrenzen
      map.addSource('woonplaatsen', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
      map.addLayer({
        id: 'woonplaatsen-outline', type: 'line', source: 'woonplaatsen',
        maxzoom: 14,
        paint: { 'line-color': '#004494', 'line-width': 1.5, 'line-opacity': 0.8, 'line-dasharray': [4, 2] },
      });

      // Panden
      map.addSource('panden', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
      map.addLayer({ id: 'panden-fill', type: 'fill', source: 'panden',
        filter: ['!=', ['get', 'inactief'], true],
        paint: { 'fill-color': ['interpolate', ['linear'], ['get', 'bouwjaar'],
          1900, '#3498db', 1960, '#2ecc71', 2000, '#f1c40f', 2015, '#e74c3c'],
          'fill-opacity': 0.65 } });
      map.addLayer({ id: 'panden-inactief-fill', type: 'fill', source: 'panden',
        filter: ['==', ['get', 'inactief'], true],
        layout: { visibility: 'none' },
        paint: { 'fill-color': '#888', 'fill-opacity': 0.45 } });
      map.addLayer({ id: 'panden-inactief-pattern', type: 'line', source: 'panden',
        filter: ['==', ['get', 'inactief'], true],
        layout: { visibility: 'none' },
        paint: { 'line-color': '#e74c3c', 'line-width': 1, 'line-dasharray': [3, 2] } });
      map.addLayer({ id: 'panden-outline', type: 'line', source: 'panden',
        filter: ['!=', ['get', 'inactief'], true],
        paint: { 'line-color': '#fff', 'line-width': 0.5 } });

      // Geselecteerd pand highlight: fill + outline in #004494
      map.addLayer({
        id: 'pand-highlight-fill', type: 'fill', source: 'panden',
        paint: { 'fill-color': '#004494', 'fill-opacity': 0.25 },
        filter: ['==', ['get', 'identificatie'], ''],
      });
      map.addLayer({
        id: 'pand-highlight', type: 'line', source: 'panden',
        paint: { 'line-color': '#004494', 'line-width': 2 },
        filter: ['==', ['get', 'identificatie'], ''],
      });

      map.on('click', 'panden-fill', async (e) => {
        if (activeToolRef.current !== 'navigeren') return;
        const id = e.features[0].properties.identificatie;
        const code = gemRef.current;
        if (!code) return;
        const f = ['==', ['get', 'identificatie'], id];
        map.setFilter('pand-highlight-fill', f);
        map.setFilter('pand-highlight', f);
        setGeselecteerdPandId(id);
        setGeselecteerdePanden([]);
        setGeselecteerdePercelen([]);
        setVanuitSelectie(false);
        const r = await fetch(`${API}/gemeenten/${code}/panden/${id}`);
        setDetailPand(await r.json());
      });

      function updateBbox() {
        const b = map.getBounds();
        setBbox([b.getWest().toFixed(6), b.getSouth().toFixed(6), b.getEast().toFixed(6), b.getNorth().toFixed(6)]);
      }
      map.on('moveend', () => { laadPanden(); updateBbox(); });
      map.on('load', updateBbox);

      // Perceellagen
      map.addSource('percelen-wmts', {
        type: 'raster',
        tiles: ['https://service.pdok.nl/kadaster/kadastralekaart/wmts/v5_0?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=Kadastralekaart&STYLE=default&TILEMATRIXSET=EPSG:3857&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/png'],
        tileSize: 256, attribution: '© Kadaster',
      });
      map.addLayer({ id: 'percelen-wmts', type: 'raster', source: 'percelen-wmts', layout: { visibility: 'none' }, paint: { 'raster-opacity': 0.8 } });
      map.addSource('percelen-wfs', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
      // Transparante fill op dezelfde polygon-source: maakt klikken/box-selectie
      // binnen het perceel mogelijk (de line-laag is alleen de rand → niet queryable
      // in het interieur). fill-opacity 0 = onzichtbaar maar wél queryRenderedFeatures.
      map.addLayer({ id: 'percelen-fill', type: 'fill', source: 'percelen-wfs', layout: { visibility: 'none' }, paint: { 'fill-color': '#ff8c00', 'fill-opacity': 0 }, minzoom: 15 });
      map.addLayer({ id: 'percelen-wfs', type: 'line', source: 'percelen-wfs', layout: { visibility: 'none' }, paint: { 'line-color': '#ff8c00', 'line-width': 1.5 }, minzoom: 15 });
      map.on('moveend', laadPercelen);
      map.on('click', 'percelen-fill', (e) => {
        const id = perceelIdUitFeature(e.features[0]) || 'Onbekend';
        new maplibregl.Popup().setLngLat(e.lngLat).setHTML(`<strong>Perceel</strong><br/>${id}`).addTo(map);
      });
      map.on('mouseenter', 'percelen-fill', () => { map.getCanvas().style.cursor = 'pointer'; });
      map.on('mouseleave', 'percelen-fill', () => { map.getCanvas().style.cursor = ''; });

      // Apply initial tool state in case tool changed before map loaded
      if (activeToolRef.current !== 'navigeren') {
        map.dragPan.disable();
        map.getCanvas().style.cursor = 'crosshair';
      }
    });
    mapInstanceRef.current = map;
    return () => { if (mapInstanceRef.current) { mapInstanceRef.current.remove(); mapInstanceRef.current = null; } };
  }, []);

  // Perceellaag URL bijwerken bij nieuw kaartmateriaal
  useEffect(() => {
    const km = kaartmateriaal.find(k => k.voor_perceellaag);
    if (!km) return;
    const map = mapInstanceRef.current;
    if (!map || !map.isStyleLoaded()) return;
    try {
      const vis = map.getLayoutProperty('percelen-wmts', 'visibility');
      if (map.getLayer('percelen-wmts')) map.removeLayer('percelen-wmts');
      if (map.getSource('percelen-wmts')) map.removeSource('percelen-wmts');
      map.addSource('percelen-wmts', { type: 'raster', tiles: [km.url], tileSize: 256, attribution: '© Kadaster' });
      map.addLayer({ id: 'percelen-wmts', type: 'raster', source: 'percelen-wmts', layout: { visibility: vis || 'none' }, paint: { 'raster-opacity': 0.8 } });
    } catch(e) {}
  }, [kaartmateriaal]);

  async function laadPanden() {
    const map = mapInstanceRef.current; const code = gemRef.current;
    if (!map || !code) return;
    const b = map.getBounds();
    const url = `${API}/gemeenten/${code}/panden?minlng=${b.getWest()}&minlat=${b.getSouth()}&maxlng=${b.getEast()}&maxlat=${b.getNorth()}`;
    const data = await fetch(url).then(r => r.json()).catch(() => null);
    if (data && map.getSource('panden')) map.getSource('panden').setData(data);
  }

  async function laadWoonplaatsen(code) {
    const map = mapInstanceRef.current;
    if (!map || !code) return;
    const data = await fetch(`${API}/gemeenten/${code}/woonplaatsen-geojson`).then(r => r.json()).catch(() => null);
    if (data && map.getSource('woonplaatsen')) map.getSource('woonplaatsen').setData(data);
  }

  async function laadPercelen() {
    const map = mapInstanceRef.current;
    if (!map || !laagInstellingenRef.current.percelen?.aan || map.getZoom() < 15) return;
    const b = map.getBounds();
    const url = `https://service.pdok.nl/kadaster/kadastralekaart/wfs/v5_0?service=WFS&version=2.0.0&request=GetFeature&typeName=kadastralekaart:perceel&outputFormat=application/json&bbox=${b.getWest()},${b.getSouth()},${b.getEast()},${b.getNorth()},EPSG:4326&count=200`;
    const data = await fetch(url).then(r => r.json()).catch(() => null);
    if (data && map.getSource('percelen-wfs')) map.getSource('percelen-wfs').setData(data);
  }

  // PDOK kadastralekaart v5 levert per perceel o.a. perceelnummer (getal, niet
  // landelijk uniek) en identificatieLokaalID (unieke BRK-ID). De backend-scan keyt
  // momenteel op perceelnummer (bronnen/perceel.py _wfs_ophalen_op_id), dus dat is
  // het primaire kopieer-ID; identificatieLokaalID als fallback.
  function perceelIdUitFeature(f) {
    const p = f.properties || {};
    if (p.perceelnummer !== undefined && p.perceelnummer !== null) return String(p.perceelnummer);
    return p.kadastraleAanduiding || p.perceelidentificatie || p.identificatieLokaalID || null;
  }

  function voerSelectieUit(map, schermPuntenArray) {
    // schermPuntenArray: [{x, y}, ...] — voor rechthoek 2 punten, voor polygoon 3+
    const xs = schermPuntenArray.map(p => p.x);
    const ys = schermPuntenArray.map(p => p.y);
    const box = [[Math.min(...xs), Math.min(...ys)], [Math.max(...xs), Math.max(...ys)]];
    const isPolygoon = schermPuntenArray.length > 2;

    // queryRenderedFeatures accepteert alleen een bbox (de envelope). Bij een polygoon
    // levert dat over-selectie: alles in de omvattende rechthoek. Verfijn daarom op de
    // werkelijke vorm — een feature telt mee als zijn centroid binnen de polygoon valt.
    // Bij een rechthoek (2 punten) is box == vorm, dus geen extra filter nodig.
    function inSelectie(geom) {
      if (!isPolygoon) return true;
      const c = geomCentroidLngLat(geom);
      if (!c) return false;
      const s = map.project(c);
      return puntInPolygoon(s.x, s.y, schermPuntenArray);
    }

    const pandFeatures = map.queryRenderedFeatures(box, { layers: ['panden-fill'] })
      .filter(f => inSelectie(f.geometry));
    const panden = [...new Set(pandFeatures.map(f => f.properties.identificatie).filter(Boolean))];

    // Perceel-IDs primair uit de pand-koppeling (primair_perceel_id, gecachet in de
    // panden-data → geen zoom/perceellaag nodig). Aangevuld met de WFS-fill als die
    // zichtbaar is (zoom ≥ 15), voor percelen zonder gekoppeld pand.
    const perceelSet = new Set();
    pandFeatures.forEach(f => {
      const pid = f.properties.primair_perceel_id;
      if (pid !== undefined && pid !== null && pid !== '') perceelSet.add(String(pid));
    });
    if (map.getLayer('percelen-fill')) {
      map.queryRenderedFeatures(box, { layers: ['percelen-fill'] })
        .filter(f => inSelectie(f.geometry))
        .map(perceelIdUitFeature).filter(Boolean).forEach(id => perceelSet.add(String(id)));
    }
    return { panden, percelen: [...perceelSet] };
  }

  function handleCanvasMouseDown(e) {
    const tool = activeToolRef.current;
    if (tool === 'navigeren') return;
    const rect = e.currentTarget.getBoundingClientRect();
    const pt = { x: e.clientX - rect.left, y: e.clientY - rect.top };
    if (tool === 'rechthoek') {
      setStartPunt(pt);
      setMuisPunt(pt);
    } else if (tool === 'polygoon') {
      // snapping: als binnen 12px van eerste punt, sluit polygoon
      const punten = tekenPuntenRef.current;
      if (punten.length >= 3) {
        const eerste = punten[0];
        const dx = pt.x - eerste.x, dy = pt.y - eerste.y;
        if (Math.sqrt(dx*dx + dy*dy) < 12) {
          // sluit polygoon
          const map = mapInstanceRef.current;
          if (map) {
            verwerkSelectie(voerSelectieUit(map, punten), map);
          }
          setTekenPunten([]);
          setMuisPunt(null);
          setSnapActief(false);
          setActiveTool('navigeren');
          return;
        }
      }
      setTekenPunten(prev => [...prev, pt]);
    }
  }

  function handleCanvasMouseMove(e) {
    const tool = activeToolRef.current;
    if (tool === 'navigeren') return;
    const rect = e.currentTarget.getBoundingClientRect();
    const pt = { x: e.clientX - rect.left, y: e.clientY - rect.top };
    setMuisPunt(pt);
    if (tool === 'polygoon') {
      const punten = tekenPuntenRef.current;
      if (punten.length >= 3) {
        const eerste = punten[0];
        const dx = pt.x - eerste.x, dy = pt.y - eerste.y;
        setSnapActief(Math.sqrt(dx*dx + dy*dy) < 12);
      }
    }
  }

  function handleCanvasMouseUp(e) {
    const tool = activeToolRef.current;
    if (tool !== 'rechthoek') return;
    const sp = startPuntRef.current;
    if (!sp) return;
    const rect = e.currentTarget.getBoundingClientRect();
    const pt = { x: e.clientX - rect.left, y: e.clientY - rect.top };
    // Minimum grootte 5px zodat kleine klikken geen lege selectie triggeren
    if (Math.abs(pt.x - sp.x) < 5 && Math.abs(pt.y - sp.y) < 5) {
      setStartPunt(null); setMuisPunt(null);
      return;
    }
    const map = mapInstanceRef.current;
    if (map) {
      verwerkSelectie(voerSelectieUit(map, [sp, pt]), map);
    }
    setStartPunt(null);
    setMuisPunt(null);
    setActiveTool('navigeren');
  }

  function verwerkSelectie(selectie, map) {
    const panden = selectie.panden || [];
    const percelen = selectie.percelen || [];
    setGeselecteerdePanden(panden);
    setGeselecteerdePercelen(percelen);
    setDetailPand(null);
    setVanuitSelectie(false);
    if (panden.length > 0) {
      map.setFilter('pand-highlight-fill', ['in', ['get', 'identificatie'], ['literal', panden]]);
      map.setFilter('pand-highlight', ['in', ['get', 'identificatie'], ['literal', panden]]);
    } else {
      const leeg = ['==', ['get', 'identificatie'], ''];
      map.setFilter('pand-highlight-fill', leeg);
      map.setFilter('pand-highlight', leeg);
    }
  }

  async function openPandVanuitSelectie(id) {
    const code = gemRef.current;
    if (!code) return;
    const map = mapInstanceRef.current;
    try {
      const r = await fetch(`${API}/gemeenten/${code}/panden/${id}`);
      if (!r.ok) return;
      const data = await r.json();
      setDetailPand(data);
      setVanuitSelectie(true);
      if (map) {
        map.setFilter('pand-highlight-fill', ['==', ['get', 'identificatie'], id]);
        map.setFilter('pand-highlight', ['==', ['get', 'identificatie'], id]);
      }
    } catch (_) {}
  }

  useEffect(() => {
    function onKeyDown(e) {
      if (e.key === 'Escape') {
        setActiveTool('navigeren');
        setTekenPunten([]);
        setStartPunt(null);
        setMuisPunt(null);
        setSnapActief(false);
      }
      if (e.key === 'Backspace' && activeToolRef.current === 'polygoon'
          && !['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName)) {
        e.preventDefault();
        setTekenPunten(prev => prev.slice(0, -1));
      }
    }
    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, []);

  useEffect(() => {
    if (geselecteerdeGemeente) {
      laadPanden();
      laadWoonplaatsen(geselecteerdeGemeente);
      if (mapInstanceRef.current) laadResultaten(geselecteerdeGemeente, mapInstanceRef.current);
      const gem = gemeenten.find(g => g.code === geselecteerdeGemeente);
      if (gem?.bbox && mapInstanceRef.current) {
        const [minlng, minlat, maxlng, maxlat] = gem.bbox;
        mapInstanceRef.current.fitBounds([[minlng, minlat], [maxlng, maxlat]], { padding: 40, animate: true });
      }
    }
  }, [geselecteerdeGemeente]);

  useEffect(() => {
    if (kaartmateriaal.length > 0 && achtergrondId === null) {
      const standaard = kaartmateriaal.find(k => k.voor_kaart && k.type === 'wmts') || kaartmateriaal.find(k => k.voor_kaart);
      if (standaard) setAchtergrondId(standaard.id);
    }
  }, [kaartmateriaal]);

  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map || achtergrondId === null) return;
    const km = kaartmateriaal.find(k => k.id === achtergrondId);
    if (!km) return;
    const tileUrl = tileUrlVoorKaartmateriaal(km);
    if (!tileUrl || !map.getSource('brt')) return;
    map.getLayer('brt') && map.removeLayer('brt');
    map.removeSource('brt');
    map.addSource('brt', { type: 'raster', tiles: [tileUrl], tileSize: 256 });
    const onderlaag = map.getLayer('woonplaatsen-outline') ? 'woonplaatsen-outline' : map.getLayer('panden-fill') ? 'panden-fill' : undefined;
    map.addLayer({ id: 'brt', type: 'raster', source: 'brt' }, onderlaag);
  }, [achtergrondId, kaartmateriaal]);

  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map) return;
    const detectieLayers = [
      'resultaten-zonnepanelen-fill', 'resultaten-zonnepanelen-line',
      'resultaten-dakkapellen-fill',  'resultaten-dakkapellen-line',
      'resultaten-contourafwijking-fill', 'resultaten-contourafwijking-line',
    ];
    detectieLayers.forEach(lid => {
      if (!map.getLayer(lid)) return;
      if (nietAanwezigZichtbaar) { map.setFilter(lid, null); }
      else { map.setFilter(lid, ['==', ['get', 'aanwezig'], true]); }
    });
  }, [nietAanwezigZichtbaar]);

  useEffect(() => {
    const map = mapInstanceRef.current;
    if (!map) return;
    const vis = inactiefZichtbaar ? 'visible' : 'none';
    try { map.setLayoutProperty('panden-inactief-fill', 'visibility', vis); } catch(e) {}
    try { map.setLayoutProperty('panden-inactief-pattern', 'visibility', vis); } catch(e) {}
  }, [inactiefZichtbaar]);

  function handleDragDrop(doelId) {
    if (!dragBron || !doelId || dragBron === doelId) { setDragDoel(null); return; }
    const volgorde = [...lagenVolgorde];
    const vanIdx = volgorde.indexOf(dragBron);
    const naarIdx = volgorde.indexOf(doelId);
    if (vanIdx === -1 || naarIdx === -1) return;
    volgorde.splice(vanIdx, 1);
    volgorde.splice(naarIdx, 0, dragBron);
    setLagenVolgorde(volgorde);
    setDragBron(null); setDragDoel(null);
    // Pas MapLibre volgorde aan: lijst boven = voorgrond, dus omgekeerd = van achter naar voren
    const map = mapInstanceRef.current;
    if (!map) return;
    const omgekeerd = [...volgorde].reverse();
    omgekeerd.forEach((id, i) => {
      const laagConf = LAGEN_CONFIG.find(l => l.id === id);
      if (!laagConf) return;
      const volgendConf = LAGEN_CONFIG.find(l => l.id === omgekeerd[i + 1]);
      const beforeId = volgendConf ? volgendConf.mapLayers[0] : undefined;
      laagConf.mapLayers.forEach(lid => { try { map.moveLayer(lid, beforeId); } catch(e) {} });
    });
  }

  async function zoek(q) {
    setZoekterm(q);
    if (q.length < 2 || !geselecteerdeGemeente) { setSuggesties([]); return; }
    const qt = q.trim();
    if (/^\d{10,}$/.test(qt) || /^[\dA-Za-z]{4,}([-_][\dA-Za-z]+)+$/.test(qt)) {
      const data = await fetch(`${API}/gemeenten/${geselecteerdeGemeente}/zoek-id?id=${encodeURIComponent(q.trim())}`).then(r => r.json()).catch(() => []);
      setSuggesties(data);
    } else {
      const data = await fetch(`${API}/gemeenten/${geselecteerdeGemeente}/zoek?q=${encodeURIComponent(q)}`).then(r => r.json()).catch(() => []);
      setSuggesties(data);
    }
  }

  function navigeerNaar(sug) {
    setSuggesties([]);
    const isId = ['Pand', 'VBO', 'Adres-ID', 'Perceel'].includes(sug.straatnaam);
    setZoekterm(isId ? (sug.identificatie || '') : `${sug.straatnaam} ${sug.huisnummer}${sug.huisletter||''}`);
    if (sug.geometry?.coordinates && mapInstanceRef.current) mapInstanceRef.current.flyTo({ center: sug.geometry.coordinates, zoom: 17 });
    if (sug.pand_identificatie && mapInstanceRef.current) {
      const f = ['==', ['get', 'identificatie'], sug.pand_identificatie];
      mapInstanceRef.current.setFilter('pand-highlight-fill', f);
      mapInstanceRef.current.setFilter('pand-highlight', f);
      setGeselecteerdPandId(sug.pand_identificatie);
    }
  }

  async function laadResultaten(gemeenteCode, map) {
    const zekerheidKleur = ['match', ['get', 'zekerheid'],
      'hoog',   '#22c55e',
      'midden', '#fb923c',
      'laag',   '#ef4444',
      '#888'
    ];
    const perceelObjectKleur = ['match', ['get', 'object_type'],
      'contourafwijking', '#ef4444',
      'zonnepanelen', '#eab308',
      'natuurlijk', '#22c55e',
      'onzeker', '#64748b',
      '#06b6d4'
    ];
    const types = [
      { type: 'zonnepanelen', laagId: 'zonnepanelen', sourceId: 'resultaten-zonnepanelen', fillId: 'resultaten-zonnepanelen-fill', lineId: 'resultaten-zonnepanelen-line' },
      { type: 'dakkapel',     laagId: 'dakkapellen', sourceId: 'resultaten-dakkapellen',  fillId: 'resultaten-dakkapellen-fill',  lineId: 'resultaten-dakkapellen-line' },
      { type: 'contour',      laagId: 'contourafwijking', sourceId: 'resultaten-contourafwijking', fillId: 'resultaten-contourafwijking-fill', lineId: 'resultaten-contourafwijking-line' },
    ];
    for (const { type, laagId, sourceId, fillId, lineId } of types) {
      try {
        const r = await fetch(`${API}/gemeenten/${gemeenteCode}/resultaten-geojson?detectie_type=${type}`);
        const geojson = await r.json();
        const zichtbaarheid = laagInstellingenRef.current[laagId]?.aan ? 'visible' : 'none';
        // Remove old layers/source
        if (map.getLayer(lineId))  map.removeLayer(lineId);
        if (map.getLayer(fillId))  map.removeLayer(fillId);
        // Also remove legacy circle layer if present (migration)
        if (map.getLayer(sourceId)) map.removeLayer(sourceId);
        if (map.getSource(sourceId)) map.removeSource(sourceId);
        map.addSource(sourceId, { type: 'geojson', data: geojson });
        // Fill layer
        map.addLayer({
          id: fillId, type: 'fill', source: sourceId,
          layout: { visibility: zichtbaarheid },
          paint: {
            'fill-color': zekerheidKleur,
            'fill-opacity': 0.4,
          },
        });
        // Outline layer — dashed if bron='handmatig'
        map.addLayer({
          id: lineId, type: 'line', source: sourceId,
          layout: { visibility: zichtbaarheid },
          paint: {
            'line-color': zekerheidKleur,
            'line-width': 2,
            'line-dasharray': ['case', ['==', ['get', 'bron'], 'handmatig'], ['literal', [4, 2]], ['literal', [1]]],
          },
        });
      } catch(e) {}
    }

    try {
      const r = await fetch(`${API}/gemeenten/${gemeenteCode}/perceel-objecten-geojson`);
      const geojson = await r.json();
      const zichtbaarheid = laagInstellingenRef.current['perceel-objecten']?.aan ? 'visible' : 'none';
      if (map.getLayer('perceel-objecten-line')) map.removeLayer('perceel-objecten-line');
      if (map.getLayer('perceel-objecten-fill')) map.removeLayer('perceel-objecten-fill');
      if (map.getSource('perceel-objecten')) map.removeSource('perceel-objecten');
      map.addSource('perceel-objecten', { type: 'geojson', data: geojson });
      map.addLayer({
        id: 'perceel-objecten-fill', type: 'fill', source: 'perceel-objecten',
        layout: { visibility: zichtbaarheid },
        paint: {
          'fill-color': perceelObjectKleur,
          'fill-opacity': 0.35,
        },
      });
      map.addLayer({
        id: 'perceel-objecten-line', type: 'line', source: 'perceel-objecten',
        layout: { visibility: zichtbaarheid },
        paint: {
          'line-color': perceelObjectKleur,
          'line-width': 2.5,
        },
      });
    } catch(e) {}

    // Click popup voor contourafwijking-laag
    map.on('click', 'resultaten-contourafwijking-fill', (e) => {
      const props = e.features[0].properties;
      map.getCanvas().style.cursor = '';
      new maplibregl.Popup()
        .setLngLat(e.lngLat)
        .setHTML(`
          <strong>${(props.subtype || 'afwijking').toUpperCase()}</strong><br/>
          Zekerheid: ${props.zekerheid}<br/>
          Oppervlak: ${props.component_area_m2 ?? '?'} m²
        `)
        .addTo(map);
    });
    map.on('mouseenter', 'resultaten-contourafwijking-fill', () => { map.getCanvas().style.cursor = 'pointer'; });
    map.on('mouseleave', 'resultaten-contourafwijking-fill', () => { map.getCanvas().style.cursor = ''; });

    map.on('click', 'perceel-objecten-fill', (e) => {
      const props = e.features[0].properties;
      const oppervlakte = props.oppervlakte_m2 ?? props.component_area_m2 ?? '?';
      new maplibregl.Popup()
        .setLngLat(e.lngLat)
        .setHTML(`
          <strong>${(props.subtype || props.object_type || 'object').toUpperCase()}</strong><br/>
          Type: ${props.object_type || '?'}<br/>
          Perceel: ${props.perceel_id || '?'}<br/>
          Pand: ${props.gekoppeld_pand_id || 'geen koppeling'}<br/>
          Zekerheid: ${props.zekerheid || '?'}<br/>
          Oppervlak: ${oppervlakte} m²
        `)
        .addTo(map);
    });
    map.on('mouseenter', 'perceel-objecten-fill', () => { map.getCanvas().style.cursor = 'pointer'; });
    map.on('mouseleave', 'perceel-objecten-fill', () => { map.getCanvas().style.cursor = ''; });
  }

  const heeftDetectieAan = ['zonnepanelen','dakkapellen','contourafwijking','perceel-objecten'].some(id => laagInstellingen[id].aan);

  function startPanelResize(e) {
    e.preventDefault();
    const startX = e.clientX;
    const startBreedte = panelBreedte;
    function onMove(e) {
      const delta = startX - e.clientX;
      setPanelBreedte(Math.max(200, Math.min(600, startBreedte + delta)));
    }
    function onUp() {
      document.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseup', onUp);
    }
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseup', onUp);
  }

  return (
    <div className="bd-page bd-page--flush">

      {/* ── Centric toolbar ── */}
      <div className="bd-map-toolbar">
        <span className="bd-map-gemeente-label">Gemeente:</span>
        <select className="bd-map-gemeente-select" value={geselecteerdeGemeente} onChange={e => setGeselecteerdeGemeente(e.target.value)}>
          <option value="">— Selecteer —</option>
          {gemeenten.filter(g=>g.status==='klaar').map(g => <option key={g.code} value={g.code}>{g.naam}</option>)}
        </select>

        <div className="bd-map-toolbar-sep" />
        <button className={'bd-tool-btn' + (activeTool==='navigeren' ? ' is-active' : '')}
          data-tip="Navigeren"
          onClick={() => setActiveTool('navigeren')}>
          <Icon name="navigation" size={17} />
        </button>
        <div className="bd-map-toolbar-sep" />
        <button className={'bd-tool-btn' + (activeTool==='rechthoek' ? ' is-active' : '')}
          data-tip="Rechthoek selecteren"
          onClick={() => setActiveTool(t => t==='rechthoek' ? 'navigeren' : 'rechthoek')}>
          <Icon name="mouse-pointer-2" size={17} />
        </button>
        <button className={'bd-tool-btn' + (activeTool==='polygoon' ? ' is-active' : '')}
          data-tip="Polygoon selecteren"
          onClick={() => setActiveTool(t => t==='polygoon' ? 'navigeren' : 'polygoon')}>
          <Icon name="pentagon" size={17} />
        </button>
        <button className="bd-tool-btn" data-tip="Pand identificeren"><Icon name="circle-dot" size={17} /></button>
        <div className="bd-map-toolbar-sep" />

        <div className="bd-map-search">
          <span className="bd-map-search-icon"><Icon name="search" size={14} /></span>
          <input placeholder="Zoek adres, BAG-ID of perceel-ID…" value={zoekterm} onChange={e => zoek(e.target.value)} />
          {suggesties.length > 0 && (
            <div className="bd-map-search-results">
              {suggesties.map((s, i) => {
                const isId = !s.straatnaam || ['Pand','VBO','Adres-ID'].includes(s.straatnaam);
                return (
                  <div key={i} className="bd-map-search-result" onMouseDown={() => navigeerNaar(s)}>
                    {isId
                      ? <><span style={{fontWeight:600}}>{s.straatnaam}</span><span style={{color:'var(--text-muted)',marginLeft:8,fontFamily:'monospace'}}>{s.identificatie}</span></>
                      : <><span style={{fontWeight:600}}>{s.straatnaam} {s.huisnummer}{s.huisletter||''}</span><span style={{color:'var(--text-muted)',marginLeft:8}}>{s.postcode} {s.woonplaats}</span></>}
                  </div>
                );
              })}
            </div>
          )}
        </div>

        <button className="bd-tool-btn" data-tip="Coördinaten invoeren"><Icon name="scan" size={17} /></button>
        <button className="bd-tool-btn" data-tip="Afstand meten"><Icon name="ruler" size={17} /></button>
        <button className="bd-tool-btn" data-tip="Afdrukken"><Icon name="printer" size={17} /></button>

        <div className="bd-map-toolbar-spacer" />
        <button className={'bd-tool-btn' + (lagenPanelOpen ? ' is-active' : '')} data-tip="Kaartlagen" onClick={() => setLagenPanelOpen(o => !o)}>
          <Icon name="layers" size={17} />
        </button>
      </div>

      {/* ── Kaartgebied ── */}
      <div className="bd-map-stage">
        <div className="bd-map-canvas" style={{position:'relative'}}
          onMouseDown={handleCanvasMouseDown}
          onMouseMove={handleCanvasMouseMove}
          onMouseUp={handleCanvasMouseUp}>
          <div ref={mapRef} style={{width:'100%', height:'100%'}} />
          <SelectieOverlay
            mode={activeTool}
            tekenPunten={tekenPunten}
            startPunt={startPunt}
            muisPunt={muisPunt}
            snapActief={snapActief}
          />
        </div>

        {/* ── Detail paneel: selectiemodus of panddetail ── */}
        {(geselecteerdePanden.length > 0 || geselecteerdePercelen.length > 0 || detailPand) && (
          <div className="bd-detail-panel">

            {/* Selectielijst */}
            {!detailPand && (geselecteerdePanden.length > 0 || geselecteerdePercelen.length > 0) && (
              <>
                <div className="bd-detail-head">
                  <h3>{[
                    geselecteerdePanden.length > 0 ? `${geselecteerdePanden.length} panden` : null,
                    geselecteerdePercelen.length > 0 ? `${geselecteerdePercelen.length} percelen` : null,
                  ].filter(Boolean).join(' + ')} geselecteerd</h3>
                  <Btn kind="ghost" size="sm" icon="x" aria-label="Sluiten" onClick={() => {
                    setGeselecteerdePanden([]);
                    setGeselecteerdePercelen([]);
                    setDetailPand(null);
                    setActiveTool('navigeren');
                    if (mapInstanceRef.current) {
                      const leeg = ['==', ['get', 'identificatie'], ''];
                      mapInstanceRef.current.setFilter('pand-highlight-fill', leeg);
                      mapInstanceRef.current.setFilter('pand-highlight', leeg);
                    }
                  }} />
                </div>
                {/* Beide kopieerknoppen samen bovenaan (buiten de scroll), zodat de
                    perceel-knop niet onder de volledige pand-lijst verdwijnt. */}
                <div style={{display:'flex', gap:'var(--space-2)', flexWrap:'wrap',
                  padding:'var(--space-3) var(--space-4)', borderBottom:'1px solid var(--color-border)'}}>
                  {geselecteerdePanden.length > 0 && (
                    <KopieerKnop
                      tekst={geselecteerdePanden.join('\n')}
                      label="Kopieer alle pand-IDs" />
                  )}
                  {geselecteerdePercelen.length > 0 && (
                    <KopieerKnop
                      tekst={geselecteerdePercelen.join('\n')}
                      label="Kopieer alle perceel-IDs" />
                  )}
                </div>
                <div style={{overflowY:'auto', flex:1}}>
                  {geselecteerdePanden.length > 0 && (
                    <>
                      <div style={{padding:'var(--space-2) var(--space-4)', borderBottom:'1px solid var(--color-border)',
                        fontSize:'var(--font-size-xs)', color:'var(--text-muted)'}}>
                        Panden — selectie gebaseerd op zichtbare panden
                      </div>
                      {geselecteerdePanden.map(id => (
                        <div key={id}
                          className="bd-map-search-result"
                          style={{cursor:'pointer', padding:'var(--space-3) var(--space-4)',
                            borderBottom:'1px solid var(--color-border-light)', display:'flex', alignItems:'center'}}
                          onClick={() => openPandVanuitSelectie(id)}>
                          <span className="bd-mono" style={{fontSize:'var(--font-size-xs)', color:'var(--color-primary)', flex:1}}>{id}</span>
                          <Icon name="chevron-right" size={12} style={{color:'var(--text-muted)'}} />
                        </div>
                      ))}
                    </>
                  )}
                  {geselecteerdePercelen.length > 0 && (
                    <>
                      <div style={{padding:'var(--space-2) var(--space-4)', borderBottom:'1px solid var(--color-border)',
                        fontSize:'var(--font-size-xs)', color:'var(--text-muted)'}}>
                        Percelen — uit pand-koppeling (+ perceellaag indien aan, zoom ≥ 15)
                      </div>
                      {geselecteerdePercelen.map(id => (
                        <div key={id}
                          className="bd-map-search-result"
                          style={{padding:'var(--space-3) var(--space-4)',
                            borderBottom:'1px solid var(--color-border-light)', display:'flex', alignItems:'center'}}>
                          <span className="bd-mono" style={{fontSize:'var(--font-size-xs)', color:'#ff8c00', flex:1}}>{id}</span>
                        </div>
                      ))}
                    </>
                  )}
                </div>
              </>
            )}

            {/* Panddetail (ook vanuit selectie) */}
            {detailPand && (
              <>
                <div className="bd-detail-head">
                  {vanuitSelectie && (
                    <Btn kind="ghost" size="sm" icon="arrow-left" onClick={() => {
                      setDetailPand(null);
                      setVanuitSelectie(false);
                      const map = mapInstanceRef.current;
                      if (map && geselecteerdePanden.length > 0) {
                        map.setFilter('pand-highlight-fill', ['in', ['get', 'identificatie'], ['literal', geselecteerdePanden]]);
                        map.setFilter('pand-highlight', ['in', ['get', 'identificatie'], ['literal', geselecteerdePanden]]);
                      }
                    }}>Selectie</Btn>
                  )}
                  <h3 style={{flex:1}}>Pand detail</h3>
                  <Btn kind="ghost" size="sm" icon="x" aria-label="Sluiten" onClick={() => {
                    setDetailPand(null);
                    setGeselecteerdPandId(null);
                    setVanuitSelectie(false);
                    setGeselecteerdePanden([]);
                    setGeselecteerdePercelen([]);
                    if (mapInstanceRef.current) {
                      const leeg = ['==', ['get', 'identificatie'], ''];
                      mapInstanceRef.current.setFilter('pand-highlight-fill', leeg);
                      mapInstanceRef.current.setFilter('pand-highlight', leeg);
                    }
                  }} />
                </div>
                <div className="bd-card" style={{padding:'var(--space-4)', marginBottom:12}}>
                  <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)', textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:6}}>BAG Pand</div>
                  <button
                    className="bd-mono"
                    onClick={() => openPandDetailInData(detailPand.pand?.identificatie)}
                    title="Open dit pand in Data-detail"
                    style={{
                      display: 'inline-flex',
                      alignItems: 'center',
                      gap: 6,
                      border: 'none',
                      background: 'transparent',
                      padding: 0,
                      color: 'var(--color-primary)',
                      fontWeight: 600,
                      fontSize: 'var(--font-size-sm)',
                      cursor: 'pointer',
                      textAlign: 'left',
                    }}
                  >
                    {detailPand.pand?.identificatie}
                    <Icon name="external-link" size={12} />
                  </button>
                  <div style={{fontSize:'var(--font-size-xs)', marginTop:6, color:'var(--text-muted)'}}>Bouwjaar: <strong style={{color:'var(--text-body)'}}>{detailPand.pand?.bouwjaar}</strong></div>
                  <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)'}}>Status: <strong style={{color:'var(--text-body)'}}>{detailPand.pand?.status}</strong></div>
                  {detailPand.pand?.document_nummer && <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)', marginTop:4}}>Doc: {detailPand.pand.document_nummer} ({detailPand.pand.document_datum})</div>}
                </div>
                {detailPand.detectie?.length > 0 && (
                  <div className="bd-card" style={{padding:'var(--space-4)', marginBottom:12}}>
                    <h2 style={{margin:'0 0 10px', fontSize:'var(--font-size-sm)', fontWeight:600, display:'flex', alignItems:'center', gap:6}}>
                      <Icon name="search-check" size={14} /> Detectieresultaten
                    </h2>
                    {detailPand.detectie.map((d, i) => {
                      const icoon = DETECTIE_ICON[d.detectie_type]==='sun' ? '☀️' : DETECTIE_ICON[d.detectie_type]==='home' ? '🏗️' : '⚠️';
                      const reviewIkoon = d.beoordeling==='correct' ? '✅' : d.beoordeling==='incorrect' ? '❌' : null;
                      const analyseStatus = d.analyse_status || 'ok';
                      const aanwezigLabel = d.aanwezig === true ? 'Aanwezig' : d.aanwezig === false ? 'Niet aanwezig' : 'Onbekend';
                      const aanwezigKind = d.aanwezig === true ? 'success' : analyseStatus !== 'ok' ? 'warning' : 'neutral';
                      return (
                        <div key={i} style={{borderBottom:'1px solid var(--color-border-light)', paddingBottom:8, marginBottom:8}}>
                          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:2}}>
                            <span style={{fontSize:'var(--font-size-sm)', fontWeight:600}}>{icoon} {DETECTIE_LABEL[d.detectie_type]||d.detectie_type}</span>
                            {reviewIkoon && <span title={`Beoordeling: ${d.beoordeling}`} style={{fontSize:'var(--font-size-md)'}}>{reviewIkoon}</span>}
                          </div>
                          <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)', marginBottom:6, paddingLeft:20}}>
                            {d.ai_model||d.ai_provider||'—'} · {fmtDateTime(d.geanalyseerd_op)}
                            {d.prompt_naam && <> · {d.prompt_naam}</>}
                            {d.finish_reason && <> · finish: {d.finish_reason}</>}
                          </div>
                          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center'}}>
                            <Badge kind={aanwezigKind}>{aanwezigLabel}</Badge>
                            <Badge kind={ZEKERHEID_KIND[d.zekerheid]||'neutral'}>{d.zekerheid||'—'}</Badge>
                          </div>
                          {analyseStatus !== 'ok' && (
                            <div style={{marginTop:4}}><Badge kind="warning">{d.fout_code || analyseStatus}</Badge></div>
                          )}
                          {d.toelichting && <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)', marginTop:4}}>{d.toelichting}</div>}
                        </div>
                      );
                    })}
                  </div>
                )}
                {detailPand.verblijfsobjecten?.map((v,i) => (
                  <div key={i} className="bd-card" style={{padding:'var(--space-3) var(--space-4)', marginBottom:8}}>
                    <div style={{fontSize:'var(--font-size-sm)', fontWeight:600}}>{v.straatnaam} {v.huisnummer}{v.huisletter||''}</div>
                    <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)'}}>{v.postcode} {v.woonplaats_naam}</div>
                    <div style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)'}}>{v.gebruiksdoel} · {v.oppervlakte} m²</div>
                  </div>
                ))}
              </>
            )}

          </div>
        )}

        {/* ── Kaartlagen paneel (rechts) ── */}
        <div className={'bd-layers-panel' + (lagenPanelOpen ? '' : ' is-collapsed')}
          style={lagenPanelOpen ? {width: panelBreedte} : {}}>
          <div className="bd-layers-resize-handle" onMouseDown={startPanelResize} />
          <div className="bd-layers-header">
            <span className="bd-layers-title"><Icon name="layers" size={15} /> Kaartlagen</span>
            <button className="bd-layers-close" onClick={() => setLagenPanelOpen(false)}><Icon name="x" size={13} /></button>
          </div>
          <div className="bd-layers-list">

            {/* Achtergrondlagen uit kaartmateriaal */}
            {kaartmateriaal.filter(k => k.voor_kaart).length > 0 && (
              <div style={{padding:'6px 14px 4px', borderBottom:'1px solid #f0f4f8'}}>
                <div style={{fontSize:10, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-muted)', marginBottom:4}}>Achtergrond</div>
                {kaartmateriaal.filter(k => k.voor_kaart).map(k => (
                  <div key={k.id} className="bd-layer-row" style={{padding:'4px 0'}} onClick={() => setAchtergrondId(k.id)}>
                    <span className="bd-layer-drag" style={{opacity:0}}><Icon name="grip-vertical" size={11} /></span>
                    <span className="bd-layer-chevron is-hidden"><Icon name="chevron-right" size={9} /></span>
                    <span className={'bd-layer-check' + (achtergrondId === k.id ? ' is-on' : '')}>
                      {achtergrondId === k.id && <Icon name="check" size={9} style={{color:'#fff', strokeWidth:3}} />}
                    </span>
                    <span className="bd-layer-swatch" style={{background:'#94a3b8', borderRadius:'50%'}} />
                    <span className={'bd-layer-name' + (achtergrondId === k.id ? '' : ' is-off')}>{k.naam}{k.jaar ? ` (${k.jaar})` : ''}</span>
                  </div>
                ))}
              </div>
            )}

            {/* Overige lagen — sleep om volgorde te wijzigen (boven = voorgrond) */}
            {lagenVolgorde.map(id => {
              const laag = LAGEN_CONFIG.find(l => l.id === id);
              if (!laag) return null;
              return (
                <LaagRij key={laag.id} laag={laag}
                  laagInstellingen={laagInstellingen}
                  laagInstellingenRef={laagInstellingenRef}
                  setLaagInstellingen={setLaagInstellingen}
                  mapInstanceRef={mapInstanceRef}
                  laadPercelen={laadPercelen}
                  onDragStart={id => setDragBron(id)}
                  onDragOver={id => setDragDoel(id)}
                  onDrop={handleDragDrop}
                  isDragOver={dragDoel === laag.id}
                />
              );
            })}

            {/* Inactieve panden */}
            <div className="bd-layers-section">
              <div className="bd-layer-row" onClick={() => setInactiefZichtbaar(v => !v)}>
                <span className="bd-layer-drag"><Icon name="grip-vertical" size={11} /></span>
                <span className="bd-layer-chevron is-hidden"><Icon name="chevron-right" size={9} /></span>
                <span className={'bd-layer-check' + (inactiefZichtbaar ? ' is-on' : '')} onClick={e => { e.stopPropagation(); setInactiefZichtbaar(v => !v); }}>
                  {inactiefZichtbaar && <Icon name="check" size={9} style={{color:'#fff', strokeWidth:3}} />}
                </span>
                <span className="bd-layer-swatch" style={{background:'#888'}} />
                <span className={'bd-layer-name' + (inactiefZichtbaar ? '' : ' is-off')}>Inactieve panden</span>
              </div>
            </div>

            {/* Zekerheidslegenda */}
            {heeftDetectieAan && (
              <div style={{padding:'8px 14px 10px', borderTop:'1px solid var(--color-border-light)', marginTop:4}}>
                <div style={{fontSize:10, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-muted)', marginBottom:6}}>Zekerheid detectie</div>
                <div style={{fontSize:10, color:'var(--text-muted)', textTransform:'uppercase', marginBottom:3}}>Aanwezig</div>
                {[{k:'#1a9e4a',l:'Hoog'},{k:'#f1c40f',l:'Midden'},{k:'#e67e22',l:'Laag'}].map(({k,l}) => (
                  <div key={l} className="bd-layer-legend-item"><div className="bd-layer-legend-swatch" style={{background:k}} /><span className="bd-layer-legend-label">{l}</span></div>
                ))}
                <div style={{height:1, background:'var(--color-border-light)', margin:'6px 0'}} />
                <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:3}}>
                  <span style={{fontSize:10, color:'var(--text-muted)', textTransform:'uppercase'}}>Niet aanwezig</span>
                  <label style={{display:'flex', alignItems:'center', gap:3, cursor:'pointer', fontSize:10, color:'var(--text-muted)'}}>
                    <input type="checkbox" checked={nietAanwezigZichtbaar} onChange={e => setNietAanwezigZichtbaar(e.target.checked)} style={{accentColor:'var(--color-primary)', width:11, height:11}} />
                    toon
                  </label>
                </div>
                {[{k:'#c0392b',l:'Hoog'},{k:'#e74c3c',l:'Midden'},{k:'#f1948a',l:'Laag'}].map(({k,l}) => (
                  <div key={l} className="bd-layer-legend-item" style={{opacity: nietAanwezigZichtbaar ? 1 : 0.3}}>
                    <div className="bd-layer-legend-swatch" style={{background:k}} /><span className="bd-layer-legend-label">{l}</span>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>

      {/* ── Legenda + live bbox ── */}
      <div className="bd-map-legend">
        <span style={{fontWeight:600, color:'var(--text-body)', textTransform:'uppercase', fontSize:'var(--font-size-xs)', letterSpacing:'0.06em'}}>Bouwjaar</span>
        <span className="bd-map-legend-item"><span className="bd-map-legend-swatch" style={{background:'#3498db'}}/> voor 1960</span>
        <span className="bd-map-legend-item"><span className="bd-map-legend-swatch" style={{background:'#2ecc71'}}/> 1960–2000</span>
        <span className="bd-map-legend-item"><span className="bd-map-legend-swatch" style={{background:'#f1c40f'}}/> 2000–2015</span>
        <span className="bd-map-legend-item"><span className="bd-map-legend-swatch" style={{background:'#e74c3c'}}/> na 2015</span>
        <span style={{flex:1}} />
        {bbox && (
          <span style={{display:'flex', alignItems:'center', gap:6}}>
            <span style={{fontSize:'var(--font-size-xs)', color:'var(--text-muted)', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.06em'}}>Bbox:</span>
            <span style={{fontFamily:'monospace', fontSize:'var(--font-size-xs)', color:'var(--text-body)', userSelect:'all'}}>{bbox.join(',')}</span>
            <BboxKopieerKnop waarde={bbox.join(',')} />
          </span>
        )}
      </div>
    </div>
  );
}

window.SchermKaart = SchermKaart;
