// Map screen — Mapbox GL map with geofence and family interactions

function circleGeo([lng, lat], radiusM, n = 64) {
  const coords = [];
  const km = radiusM / 1000;
  for (let i = 0; i <= n; i++) {
    const a = (i / n) * 2 * Math.PI;
    const dLat = (km * Math.sin(a)) / 110.574;
    const dLng = (km * Math.cos(a)) / (111.32 * Math.cos((lat * Math.PI) / 180));
    coords.push([lng + dLng, lat + dLat]);
  }
  return { type: 'Polygon', coordinates: [coords] };
}

function distM(lat1, lon1, lat2, lon2) {
  const R = 6371000;
  const dLat = ((lat2 - lat1) * Math.PI) / 180;
  const dLon = ((lon2 - lon1) * Math.PI) / 180;
  const a = Math.sin(dLat / 2) ** 2 + Math.cos((lat1 * Math.PI) / 180) * Math.cos((lat2 * Math.PI) / 180) * Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}

function MapScreen({ store, cfg, onNav, active }) {
  const { family, geofences, addGeofence, updateGeofence, removeGeofence, trackerOffsets } = store;
  const [selectedFence, setSelectedFence] = React.useState(null);
  const [selectedMember, setSelectedMember] = React.useState(family[0]?.id || null);
  const [mode, setMode] = React.useState('family'); // family | fences | history
  const [baseStyle, setBaseStyle] = React.useState('streets');
  const [historyDays, setHistoryDays] = React.useState(7);
  const [historyEntries, setHistoryEntries] = React.useState([]);
  const [historyLoading, setHistoryLoading] = React.useState(false);
  const [offsetBusy, setOffsetBusy] = React.useState(false);
  
  // Geofence drawing — crosshair + pan-to-position + slider for radius
  // drawState: 'idle' | 'drawing' (crosshair mode) | 'naming' (preview locked, form shown)
  const [drawState, setDrawState] = React.useState('idle');
  const [previewRadius, setPreviewRadius] = React.useState(120);
  const drawCenter = React.useRef(null); // [lng, lat] locked when transitioning drawing→naming
  // Refs so map handlers always see current values without rebuilding the map
  const drawStateRef = React.useRef('idle');
  const previewRadiusRef = React.useRef(120);
  React.useEffect(() => { drawStateRef.current = drawState; }, [drawState]);
  React.useEffect(() => { previewRadiusRef.current = previewRadius; }, [previewRadius]);
  const [fenceDraft, setFenceDraft] = React.useState({ name: '', color: '#C9562E' });
  // Editing an existing fence
  const [editingFence, setEditingFence] = React.useState(null); // fence id
  const [editDraft, setEditDraft] = React.useState({ name: '', radius: 120, color: '#C9562E' });
  const [editReposition, setEditReposition] = React.useState(false); // crosshair mode for edit
  const [confirmDelete, setConfirmDelete] = React.useState(false);
  const editNewPosition = React.useRef(null); // [lng, lat] captured when confirming reposition

  const [searchQuery, setSearchQuery] = React.useState('');
  const [publicConfig, setPublicConfig] = React.useState({ mapboxToken: '', trackerUrl: '', wsUrl: '' });
  const [mapErr, setMapErr] = React.useState('');
  const [mapLoaded, setMapLoaded] = React.useState(false); // true once Mapbox fires 'idle'

  const mapNodeRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const markersRef = React.useRef({});
  const meMarkerRef = React.useRef(null);

  const hasMapbox = typeof window !== 'undefined' && !!window.mapboxgl;
  const selectedFenceObj = geofences.find(g => g.id === selectedFence);
  const selectedMemberObj = family.find(f => String(f.id) === String(selectedMember)) || family[0] || null;
  const selectedTrackerId = selectedMemberObj?.tracker_id || '';

  React.useEffect(() => {
    if (!selectedMember && family[0]?.id) setSelectedMember(family[0].id);
  }, [family, selectedMember]);

  React.useEffect(() => {
    if (!store.fetchTrackerOffsets) return;
    store.fetchTrackerOffsets().catch(() => {});
  }, []);

  React.useEffect(() => {
    if (mode !== 'history' || !selectedTrackerId || !store.fetchLocationHistory) return;
    setHistoryLoading(true);
    store.fetchLocationHistory(selectedTrackerId, historyDays)
      .then(entries => setHistoryEntries(entries))
      .finally(() => setHistoryLoading(false));
  }, [mode, selectedTrackerId, historyDays]);

  // Resize map when tab becomes active (keeps canvas size correct after display:none)
  React.useEffect(() => {
    if (active && mapRef.current) {
      requestAnimationFrame(() => mapRef.current?.resize());
    }
  }, [active]);

  const mapStyleUrl = React.useMemo(() => {
    if (baseStyle === 'sat') return 'mapbox://styles/mapbox/satellite-streets-v12';
    return 'mapbox://styles/mapbox/streets-v12';
  }, [baseStyle]);

  const setGeoJsonOnMap = React.useCallback(() => {
    if (!mapRef.current) return;
    const source = mapRef.current.getSource('geofences');
    if (!source) return;
    const features = geofences.map((z) => {
      // When editing a fence, use the draft radius/color for live preview
      const isEditing = editingFence && z.id === editingFence;
      const radius = isEditing ? (editDraft.radius || z.radius || 120) : (z.radius || 120);
      const color = isEditing ? (editDraft.color || z.color || '#3b82f6') : (z.id === selectedFence ? '#ffffff' : (z.color || '#3b82f6'));
      return {
        type: 'Feature',
        properties: { id: z.id, name: z.name, color, radius },
        geometry: circleGeo([z.lng || z.lon, z.lat], radius),
      };
    });
    source.setData({ type: 'FeatureCollection', features });
  }, [geofences, editingFence, editDraft.radius, editDraft.color]);

  const ensureGeoLayers = React.useCallback(() => {
    if (!mapRef.current) return;
    const map = mapRef.current;

    if (!map.getSource('geofences')) {
      map.addSource('geofences', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
    }
    if (!map.getLayer('geo-fill')) {
      map.addLayer({
        id: 'geo-fill',
        type: 'fill',
        source: 'geofences',
        paint: {
          'fill-color': ['coalesce', ['get', 'color'], '#3b82f6'],
          'fill-opacity': 0.08,
        },
      });
    }
    if (!map.getLayer('geo-line')) {
      map.addLayer({
        id: 'geo-line',
        type: 'line',
        source: 'geofences',
        paint: {
          'line-color': ['coalesce', ['get', 'color'], '#3b82f6'],
          'line-width': 2,
          'line-opacity': 0.7,
          'line-dasharray': [2, 2],
        },
      });
    }
    if (!map.getLayer('geo-labels')) {
      map.addLayer({
        id: 'geo-labels',
        type: 'symbol',
        source: 'geofences',
        layout: {
          'text-field': ['get', 'name'],
          'text-size': 11,
        },
        paint: {
          'text-color': '#7f6a58',
          'text-halo-color': 'rgba(255,255,255,0.75)',
          'text-halo-width': 1,
        },
      });
    }
    
    // Drawing layers
    if (!map.getSource('preview')) {
      map.addSource('preview', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
    }
    if (!map.getLayer('preview-fill')) {
      map.addLayer({ id: 'preview-fill', type: 'fill', source: 'preview', paint: { 'fill-color': '#C9562E', 'fill-opacity': 0.2 } });
    }
    if (!map.getLayer('preview-line')) {
      map.addLayer({ id: 'preview-line', type: 'line', source: 'preview', paint: { 'line-color': '#C9562E', 'line-width': 2, 'line-dasharray': [3, 2] } });
    }
    if (!map.getSource('center-dot')) {
      map.addSource('center-dot', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } });
    }
    if (!map.getLayer('center-dot')) {
      map.addLayer({ id: 'center-dot', type: 'circle', source: 'center-dot', paint: { 'circle-radius': 6, 'circle-color': '#C9562E', 'circle-stroke-width': 2, 'circle-stroke-color': '#fff' } });
    }

    setGeoJsonOnMap();
  }, []);

  // Separate effect: update geofence GeoJSON data whenever fences or edit draft change
  // This is decoupled from ensureGeoLayers so map init doesn't re-run on edits
  React.useEffect(() => {
    setGeoJsonOnMap();
  }, [setGeoJsonOnMap]);

  const fitToFamily = React.useCallback(() => {
    if (!mapRef.current || !window.mapboxgl) return;
    const tracked = family.filter(f => f.tracked && f.lat && f.lng);
    if (!tracked.length) return;
    const bounds = new window.mapboxgl.LngLatBounds();
    tracked.forEach((f) => bounds.extend([f.lng, f.lat]));
    mapRef.current.fitBounds(bounds, { padding: 70, maxZoom: 15, duration: 600 });
  }, [family]);

  const flyToFamilyMember = React.useCallback((member) => {
    if (!mapRef.current || !member) return;
    setSelectedMember(member.id);
    setMode('family');
    if (member.tracked && member.lat && member.lng) {
      mapRef.current.flyTo({ center: [member.lng, member.lat], zoom: 16, duration: 700 });
    }
  }, []);

  const flyToFence = React.useCallback((fence) => {
    if (!mapRef.current || !fence) return;
    setSelectedFence(fence.id);
    setMode('fences');
    mapRef.current.flyTo({ center: [fence.lng || fence.lon, fence.lat], zoom: 15, duration: 700 });
  }, []);

  const locateMe = React.useCallback(() => {
    if (!mapRef.current || !navigator.geolocation || !window.mapboxgl) {
      if (!navigator.geolocation) alert("Geolocation is not supported by your browser or requires HTTPS.");
      return;
    }
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        const me = [pos.coords.longitude, pos.coords.latitude];
        mapRef.current.flyTo({ center: me, zoom: 16, duration: 700 });
        if (meMarkerRef.current) {
          meMarkerRef.current.setLngLat(me);
          return;
        }
        meMarkerRef.current = new window.mapboxgl.Marker({ color: '#2A84FF' })
          .setLngLat(me)
          .setPopup(new window.mapboxgl.Popup({ offset: 22 }).setText('Your location'))
          .addTo(mapRef.current);
      },
      (err) => { alert("Could not fetch location: " + err.message); },
      { enableHighAccuracy: true, timeout: 7000 }
    );
  }, []);

  const saveFence = React.useCallback(() => {
    const name = (fenceDraft.name || '').trim();
    const [cLng, cLat] = drawCenter.current || [0, 0];
    addGeofence({
      name: name || `Zone ${geofences.length + 1}`,
      lat: cLat,
      lng: cLng,
      radius: previewRadius || 120,
      color: fenceDraft.color || '#C9562E',
      members: selectedMember ? [String(selectedMember)] : [],
    });
    setFenceDraft({ name: '', color: '#C9562E' });
    setDrawState('idle');
    setMode('fences');
    // Clear preview layers
    mapRef.current?.getSource('preview')?.setData({ type: 'FeatureCollection', features: [] });
    mapRef.current?.getSource('center-dot')?.setData({ type: 'FeatureCollection', features: [] });
  }, [addGeofence, geofences.length, fenceDraft, selectedMember, previewRadius]);

  // Enter edit mode for an existing fence
  const editFence = (fence) => {
    setEditingFence(fence.id);
    setEditDraft({ name: fence.name, radius: fence.radius || 120, color: fence.color || '#C9562E', notify: fence.notify !== false });
    setEditReposition(false);
    setConfirmDelete(false);
    setDrawState('idle');
    // Pan to the fence without changing zoom
    if (mapRef.current) {
      mapRef.current.panTo([fence.lng || fence.lon, fence.lat], { duration: 400 });
    }
  };

  const cancelEdit = () => {
    setEditingFence(null);
    setEditReposition(false);
    setConfirmDelete(false);
    editNewPosition.current = null;
    mapRef.current?.getSource('preview')?.setData({ type: 'FeatureCollection', features: [] });
    mapRef.current?.getSource('center-dot')?.setData({ type: 'FeatureCollection', features: [] });
  };

  const startEditReposition = () => {
    setEditReposition(true);
    // Show preview circle at current fence location
    const fence = geofences.find(g => g.id === editingFence);
    if (fence && mapRef.current) {
      const coords = [fence.lng, fence.lat];
      mapRef.current.getSource('preview')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: circleGeo(coords, editDraft.radius) }]
      });
      mapRef.current.getSource('center-dot')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: { type: 'Point', coordinates: coords } }]
      });
      setDrawState('drawing'); // Enables crosshair + move handler
    }
  };

  const saveEdit = () => {
    if (!editingFence) return;
    const patch = {
      name: editDraft.name.trim() || 'Zone',
      radius: editDraft.radius,
      color: editDraft.color,
      notify: editDraft.notify,
    };
    // Use stored repositioned coords if available
    if (editNewPosition.current) {
      patch.lng = editNewPosition.current[0];
      patch.lat = editNewPosition.current[1];
    }
    updateGeofence(editingFence, patch);
    cancelEdit();
  };

  const doDeleteFence = () => {
    if (!editingFence) return;
    removeGeofence(editingFence);
    cancelEdit();
  };

  React.useEffect(() => {
    fetch('/api/config/public')
      .then(r => r.json())
      .then((cfgPublic) => {
        setPublicConfig(cfgPublic || {});
      })
      .catch(() => setMapErr('Could not load map configuration.'));
  }, []);

  React.useEffect(() => {
    if (!hasMapbox || mapRef.current || !mapNodeRef.current || !publicConfig?.mapboxToken) return;
    window.mapboxgl.accessToken = publicConfig.mapboxToken;

    const aliveFamily = family.filter(f => f.lat && f.lng);
    const anchor = aliveFamily[0] || geofences[0] || { lat: 50.98146, lng: 4.572189 };
    const map = new window.mapboxgl.Map({
      container: mapNodeRef.current,
      style: mapStyleUrl,
      center: [anchor.lng || anchor.lon, anchor.lat],
      zoom: 13,
      pitch: 24,
      bearing: 0,
      attributionControl: false,
    });
    map.addControl(new window.mapboxgl.AttributionControl({ compact: true }), 'bottom-right');

    map.on('load', () => {
      ensureGeoLayers();
      setMapLoaded(true);
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          (pos) => {
             const me = [pos.coords.longitude, pos.coords.latitude];
             map.flyTo({ center: me, zoom: 14, duration: 0 });
          },
          () => {},
          { enableHighAccuracy: false, timeout: 3000 }
        );
      }
    });

    map.on('style.load', () => {
      ensureGeoLayers();
      setMapLoaded(true);
    });

    const onClick = (e) => {
      // In drawing/naming mode, clicks on the map are ignored (panning handles positioning)
      if (drawStateRef.current !== 'idle') return;
      if (map.getLayer('geo-fill')) {
        const hit = map.queryRenderedFeatures(e.point, { layers: ['geo-fill'] });
        setSelectedFence(hit.length > 0 ? hit[0].properties.id : null);
        if (hit.length > 0) setMode('fences');
      }
    };

    // map.on('move') fires on ALL map movement — touch pan, mouse drag, programmatic flyTo
    // Use it to keep the preview circle centered on the viewport when in drawing mode
    const onMapMove = () => {
      if (drawStateRef.current !== 'drawing') return;
      const center = map.getCenter();
      const r = previewRadiusRef.current;
      const coords = [center.lng, center.lat];
      map.getSource('preview')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: circleGeo(coords, r) }]
      });
      map.getSource('center-dot')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: { type: 'Point', coordinates: coords } }]
      });
    };

    // Hover cursor for idle mode
    const onMouseMove = (e) => {
      if (drawStateRef.current !== 'idle') return;
      if (!map.getLayer('geo-fill')) return;
      const hit = map.queryRenderedFeatures(e.point, { layers: ['geo-fill'] });
      map.getCanvas().style.cursor = hit.length > 0 ? 'pointer' : '';
    };

    map.on('click', onClick);
    map.on('move', onMapMove);
    map.on('mousemove', onMouseMove);
    map.on('style.load', () => ensureGeoLayers());

    mapRef.current = map;
    return () => {
      Object.values(markersRef.current).forEach((m) => m.remove());
      markersRef.current = {};
      meMarkerRef.current?.remove();
      meMarkerRef.current = null;
      map.remove();
      mapRef.current = null;
    };
    // drawState intentionally NOT in deps — drawStateRef.current is used instead
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [hasMapbox, publicConfig?.mapboxToken, mapStyleUrl]);

  // Update cursor when drawState changes
  React.useEffect(() => {
    if (!mapRef.current) return;
    const canvas = mapRef.current.getCanvas();
    canvas.style.cursor = drawState === 'drawing' ? 'grab' : '';
  }, [drawState]);

  // When radius slider changes while in drawing mode, update the preview circle
  React.useEffect(() => {
    if (drawState !== 'drawing' || !mapRef.current) return;
    const map = mapRef.current;
    const center = map.getCenter();
    const coords = [center.lng, center.lat];
    map.getSource('preview')?.setData({
      type: 'FeatureCollection',
      features: [{ type: 'Feature', geometry: circleGeo(coords, previewRadius) }]
    });
  }, [previewRadius, drawState]);

  // Re-render geofence layers when geofences change OR map first loads
  React.useEffect(() => {
    if (!mapRef.current || !mapLoaded) return;
    if (mapRef.current.isStyleLoaded()) {
      ensureGeoLayers();
    }
  }, [ensureGeoLayers, mapLoaded]);

  React.useEffect(() => {
    if (!mapRef.current || !selectedFenceObj || mode !== 'fences') return;
    mapRef.current.flyTo({ center: [selectedFenceObj.lng || selectedFenceObj.lon, selectedFenceObj.lat], zoom: 15, duration: 450 });
  }, [selectedFenceObj, mode]);

  // Re-render markers whenever family data, search query, or map load state changes.
  // Only tracked members (with real GPS coords) get a marker pin.
  React.useEffect(() => {
    if (!mapRef.current || !mapLoaded || !window.mapboxgl) return;
    const map = mapRef.current;

    // Remove all existing markers
    Object.values(markersRef.current).forEach((m) => m.remove());
    markersRef.current = {};

    const sLower = searchQuery.toLowerCase();
    const toShow = searchQuery
      ? family.filter(f => f.name.toLowerCase().includes(sLower))
      : family;

    toShow.forEach((f) => {
      if (!f.tracked || !f.lat || !f.lng) return; // only show GPS-tracked members
      const initials = (f.name || '').slice(0, 2).toUpperCase() || '??';
      const el = document.createElement('div');
      el.innerHTML = `<div class="hh-map-pin-wrap"><div class="hh-map-pin" style="background:${f.color}">${initials}</div><span class="hh-map-pin-tail"></span></div>`;

      const popup = new window.mapboxgl.Popup({ offset: 20 })
        .setHTML(`<strong>${f.name}</strong><br/>Battery ${f.battery ?? '–'}%`);

      const marker = new window.mapboxgl.Marker({ element: el, anchor: 'bottom' })
        .setLngLat([f.lng, f.lat])
        .setPopup(popup)
        .addTo(map);

      marker.getElement().addEventListener('click', () => {
        setSelectedMember(f.id);
        setMode('family');
      });
      markersRef.current[f.id] = marker;
    });
  }, [family, searchQuery, mapLoaded]);

  // Style change — only call setStyle when the URL actually changes (not on mount)
  // Use a ref to track whether this is the first run
  const prevStyleRef = React.useRef(null);
  React.useEffect(() => {
    if (!mapRef.current) return;
    if (prevStyleRef.current === mapStyleUrl) return; // no change
    if (prevStyleRef.current !== null) {
      // Only setMapLoaded(false) + setStyle when actively switching styles
      setMapLoaded(false);
      mapRef.current.setStyle(mapStyleUrl);
    }
    prevStyleRef.current = mapStyleUrl;
  }, [mapStyleUrl]);

  // startDraw: enter drawing mode — crosshair+slider panel takes over
  const startDraw = () => {
    if (drawState !== 'idle') {
      // Cancel — clear preview and return to idle
      mapRef.current?.getSource('preview')?.setData({ type: 'FeatureCollection', features: [] });
      mapRef.current?.getSource('center-dot')?.setData({ type: 'FeatureCollection', features: [] });
      setDrawState('idle');
      return;
    }
    setSelectedFence(null);
    setPreviewRadius(120);
    setMode('fences');
    setDrawState('drawing');
    // Seed preview immediately at current map center
    if (mapRef.current) {
      const c = mapRef.current.getCenter();
      const coords = [c.lng, c.lat];
      mapRef.current.getSource('preview')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: circleGeo(coords, 120) }]
      });
      mapRef.current.getSource('center-dot')?.setData({
        type: 'FeatureCollection',
        features: [{ type: 'Feature', geometry: { type: 'Point', coordinates: coords } }]
      });
    }
  };

  // confirmCenter: lock the map center as the fence position and show naming form
  const confirmCenter = () => {
    if (!mapRef.current) return;
    const c = mapRef.current.getCenter();
    drawCenter.current = [c.lng, c.lat];
    setDrawState('naming');
  };

  if (!hasMapbox) {
    return (
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
        <div className="hh-card" style={{ padding: 20, textAlign: 'center', maxWidth: 320 }}>
          <div className="hh-serif" style={{ fontSize: 24, marginBottom: 8 }}>Map unavailable</div>
          <div style={{ fontSize: 13, color: 'var(--hh-ink-mute)' }}>Mapbox GL failed to load.</div>
        </div>
      </div>
    );
  }

  if (!publicConfig?.mapboxToken) {
    return (
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
        <div className="hh-card" style={{ padding: 20, textAlign: 'center', maxWidth: 360 }}>
          <div className="hh-serif" style={{ fontSize: 24, marginBottom: 8 }}>Missing MAPBOX_TOKEN</div>
          <div style={{ fontSize: 13, color: 'var(--hh-ink-mute)' }}>{mapErr || 'Set MAPBOX_TOKEN in .env and restart HomeHub.'}</div>
        </div>
      </div>
    );
  }

  const sLower = searchQuery.toLowerCase();
  const visibleFamily = searchQuery
    ? family.filter(f => f.name.toLowerCase().includes(sLower) || (f.location && f.location.toLowerCase().includes(sLower)))
    : family;
  const visibleFences = searchQuery
    ? geofences.filter(f => f.name.toLowerCase().includes(sLower))
    : geofences;

  const now = Math.floor(Date.now() / 1000);
  const currentOffset = selectedTrackerId ? (trackerOffsets[selectedTrackerId] || { dLat: 0, dLon: 0 }) : { dLat: 0, dLon: 0 };
  const metersPerLat = 111111;
  const metersPerLon = Math.max(1, 111111 * Math.cos(((selectedMemberObj?.lat || 50) * Math.PI) / 180));
  const offsetNorthMeters = Math.round((currentOffset.dLat || 0) * metersPerLat);
  const offsetEastMeters = Math.round((currentOffset.dLon || 0) * metersPerLon);

  const adjustOffset = (northMeters, eastMeters) => {
    if (!selectedTrackerId || !store.setTrackerOffset) return;
    setOffsetBusy(true);
    store.setTrackerOffset(selectedTrackerId, {
      dLat: (currentOffset.dLat || 0) + (northMeters / metersPerLat),
      dLon: (currentOffset.dLon || 0) + (eastMeters / metersPerLon),
    }).finally(() => setOffsetBusy(false));
  };

  return (
    <div style={{ flex: 1, minHeight: 0, position: 'relative', overflow: 'hidden', background: 'var(--hh-bg)', height: '100%', marginTop: 'calc(-1 * env(safe-area-inset-top))' }}>
      <div ref={mapNodeRef} style={{ position: 'absolute', inset: 0 }} />
      {/* Warm tint — must NOT have z-index so it doesn't cover Mapbox markers */}
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(245, 231, 210, 0.16)', pointerEvents: 'none' }} />

      {/* Top chrome */}
      <div className="hh-map-topchrome-safe" style={{ position: 'absolute', top: 0, left: 0, right: 0, zIndex: 20, paddingLeft: 14, paddingRight: 14, paddingBottom: 14, display: 'flex', gap: 8, alignItems: 'center', pointerEvents: 'none' }}>
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8, background: 'var(--hh-surface)', borderRadius: 999, padding: '10px 14px', boxShadow: 'var(--hh-shadow)', pointerEvents: 'auto' }}>
          <Icon name="search" size={16} color="var(--hh-ink-mute)"/>
          <input 
            value={searchQuery}
            onChange={e => setSearchQuery(e.target.value)}
            placeholder="Search places & people"
            style={{ fontSize: 13, color: 'var(--hh-ink)', background: 'transparent', border: 'none', outline: 'none', width: '100%' }}
          />
        </div>
        <button className="press" onClick={fitToFamily} style={{ width: 40, height: 40, background: 'var(--hh-surface)', borderRadius: 999, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--hh-shadow)', pointerEvents: 'auto' }}>
          <Icon name="filter" size={18}/>
        </button>
      </div>

      {/* Crosshair — shown while positioning the geofence */}
      {drawState === 'drawing' && (
        <div style={{
          position: 'absolute', left: '50%', top: '50%',
          transform: 'translate(-50%, -50%)',
          zIndex: 25, pointerEvents: 'none',
        }}>
          <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
            <circle cx="24" cy="24" r="5" fill="white" stroke={fenceDraft.color} strokeWidth="2.5"/>
            <line x1="24" y1="2" x2="24" y2="16" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
            <line x1="24" y1="32" x2="24" y2="46" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
            <line x1="2" y1="24" x2="16" y2="24" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
            <line x1="32" y1="24" x2="46" y2="24" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
          </svg>
        </div>
      )}

      {/* Drawing panel — replaces bottom card when in drawing/naming mode */}
      {(drawState === 'drawing' || drawState === 'naming') && (
        <div style={{
          position: 'absolute', left: 12, right: 12,
          bottom: 'calc(8px + var(--hh-tabbar-h) + env(safe-area-inset-bottom))',
          zIndex: 30, borderRadius: 22,
          background: 'var(--hh-surface)',
          boxShadow: 'var(--hh-shadow-lg)',
          overflow: 'hidden',
          // Never taller than the space above the tab bar minus a top margin
          maxHeight: 'calc(100dvh - var(--hh-tabbar-h) - env(safe-area-inset-bottom) - 120px)',
          overflowY: 'auto',
        }}>
          {drawState === 'drawing' && (
            <div style={{ padding: '14px 16px 20px' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
                <div>
                  <div className="hh-serif" style={{ fontSize: 15 }}>Position geofence</div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 1 }}>Pan the map to move the crosshair</div>
                </div>
                <button onClick={startDraw} className="press" style={{ fontSize: 12, color: 'var(--hh-ink-mute)', paddingLeft: 12 }}>Cancel</button>
              </div>

              {/* Radius slider */}
              <div style={{ marginBottom: 10 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4, fontSize: 12 }}>
                  <span style={{ color: 'var(--hh-ink-soft)' }}>Radius</span>
                  <span style={{ fontWeight: 600, color: fenceDraft.color }}>{previewRadius} m</span>
                </div>
                <input
                  type="range" min="5" max="2000" step="5"
                  value={previewRadius}
                  onChange={e => setPreviewRadius(Number(e.target.value))}
                  style={{ width: '100%', accentColor: fenceDraft.color, display: 'block' }}
                />
              </div>

              {/* Color picker */}
              <div style={{ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap' }}>
                {['#C9562E','#6E8662','#5F7E91','#C99A2E','#7A4F6B','#3b82f6'].map(c => (
                  <button key={c} onClick={() => setFenceDraft(d => ({ ...d, color: c }))} style={{
                    width: 26, height: 26, borderRadius: '50%', background: c,
                    border: fenceDraft.color === c ? '3px solid var(--hh-ink)' : '2px solid transparent',
                    boxShadow: fenceDraft.color === c ? '0 0 0 2px var(--hh-surface)' : 'none',
                    flexShrink: 0,
                  }}/>
                ))}
              </div>

              <button
                onClick={confirmCenter}
                className="press"
                style={{
                  width: '100%', height: 42, borderRadius: 14,
                  background: fenceDraft.color, color: '#fff',
                  fontSize: 14, fontWeight: 600,
                  boxSizing: 'border-box',
                }}
              >
                Place here ({previewRadius}m)
              </button>
            </div>
          )}

          {drawState === 'naming' && (
            <div style={{ padding: '14px 16px 20px' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
                <div className="hh-serif" style={{ fontSize: 15 }}>Name this zone</div>
                <button onClick={startDraw} className="press" style={{ fontSize: 12, color: 'var(--hh-ink-mute)', paddingLeft: 12 }}>Cancel</button>
              </div>
              <input
                value={fenceDraft.name}
                onChange={e => setFenceDraft(d => ({ ...d, name: e.target.value }))}
                placeholder={`Zone ${geofences.length + 1}`}
                autoFocus
                style={{
                  width: '100%', height: 42, borderRadius: 12,
                  border: '1.5px solid var(--hh-line-soft)',
                  background: 'var(--hh-surface-2)',
                  padding: '0 14px', fontSize: 15, color: 'var(--hh-ink)',
                  boxSizing: 'border-box', marginBottom: 10,
                }}
              />
              <div style={{ display: 'flex', gap: 8 }}>
                <button
                  onClick={() => setDrawState('drawing')}
                  className="press"
                  style={{ flex: 1, height: 42, borderRadius: 14, background: 'var(--hh-surface-2)', fontSize: 14 }}
                >
                  ← Reposition
                </button>
                <button
                  onClick={saveFence}
                  className="press"
                  style={{ flex: 2, height: 42, borderRadius: 14, background: fenceDraft.color, color: '#fff', fontSize: 14, fontWeight: 600 }}
                >
                  Save zone
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Mode tabs */}
      <div style={{ position: 'absolute', top: 'calc(72px + env(safe-area-inset-top))', left: 0, right: 0, zIndex: 21, display: 'flex', justifyContent: 'center', gap: 6, padding: '0 14px', pointerEvents: 'none' }}>
        <div style={{ background: 'var(--hh-surface)', borderRadius: 999, padding: 3, display: 'flex', boxShadow: 'var(--hh-shadow)', pointerEvents: 'auto' }}>
          {[['family', 'People'], ['fences', 'Geofences'], ['history', 'History']].map(([id, l]) => (
            <button key={id} onClick={() => setMode(id)} className="press" style={{
              padding: '8px 14px', borderRadius: 999, fontSize: 12, fontWeight: 500,
              background: mode === id ? 'var(--hh-ink)' : 'transparent',
              color: mode === id ? 'var(--hh-bg)' : 'var(--hh-ink-soft)',
            }}>{l}</button>
          ))}
        </div>
      </div>

      {/* Bottom card — hidden when drawing/naming panel is active to prevent overlap */}
      {(drawState === 'idle' || (drawState !== 'idle' && mode !== 'fences')) && <div style={{ position: 'absolute', left: 12, right: 12, bottom: 'calc(14px + var(--hh-tabbar-h) + env(safe-area-inset-bottom))', zIndex: 30, background: 'var(--hh-surface)', borderRadius: 22, padding: 14, boxShadow: 'var(--hh-shadow-lg)', maxHeight: '44%', overflow: 'auto' }}>
        {mode === 'family' && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
              <div className="hh-serif" style={{ fontSize: 18 }}>Who's where</div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                <button className="press" onClick={locateMe} style={{ fontSize: 12, color: 'var(--hh-accent)' }}>Locate me</button>
                <button className="press" onClick={() => onNav('family')} style={{ fontSize: 12, color: 'var(--hh-accent)' }}>Manage →</button>
              </div>
            </div>
            {visibleFamily.map((f, i) => {
              let updatedStr = 'unknown';
              if (f.timestamp) {
                  const diffMins = Math.floor((now - f.timestamp) / 60);
                  if (diffMins < 1) updatedStr = 'just now';
                  else if (diffMins < 60) updatedStr = `${diffMins} min ago`;
                  else updatedStr = `${Math.floor(diffMins/60)} h ago`;
              }
              return (
              <div key={f.id} onClick={() => flyToFamilyMember(f)} className="press" style={{ display: 'flex', gap: 10, alignItems: 'center', padding: '8px 0', borderTop: i ? '1px solid var(--hh-line-soft)' : 'none', cursor: 'pointer', borderRadius: 8, background: selectedMember === f.id ? 'var(--hh-accent-tint)' : 'transparent' }}>
                <Avatar name={f.name} color={f.color} size={36}/>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{f.name} <span style={{ color: f.tracked ? 'var(--hh-sage)' : 'var(--hh-ink-mute)', fontWeight: 400, fontSize: 12 }}>· {f.tracker_id ? (f.tracked ? '● Live' : '○ Offline') : 'No tracker'}</span></div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>Battery {f.battery ?? '–'}% · {f.timestamp ? 'updated ' + (() => { const d = Math.floor((now - f.timestamp)/60); return d < 1 ? 'just now' : d < 60 ? d + ' min ago' : Math.floor(d/60) + ' h ago'; })() : 'never updated'}</div>
                </div>
                <button className="press" style={{ width: 32, height: 32, borderRadius: 999, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="route" size={16} color="var(--hh-accent)"/>
                </button>
              </div>
            )})}
            {selectedMemberObj?.tracker_id && (
              <div className="hh-card" style={{ marginTop: 12, padding: 14, background: 'linear-gradient(135deg, var(--hh-accent-tint), var(--hh-surface))' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 10 }}>
                  <div>
                    <div className="hh-serif" style={{ fontSize: 18 }}>GPS correction</div>
                    <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 2 }}>Nudge {selectedMemberObj.name}'s tracked position when the device reports a consistent offset.</div>
                  </div>
                  <button
                    className="press"
                    disabled={offsetBusy}
                    onClick={() => store.clearTrackerOffset && store.clearTrackerOffset(selectedTrackerId).catch(() => {})}
                    style={{ height: 34, padding: '0 12px', borderRadius: 999, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, color: 'var(--hh-ink-soft)' }}
                  >
                    Reset
                  </button>
                </div>
                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 12 }}>
                  <span className="hh-pill">North/South: {offsetNorthMeters > 0 ? '+' : ''}{offsetNorthMeters}m</span>
                  <span className="hh-pill">East/West: {offsetEastMeters > 0 ? '+' : ''}{offsetEastMeters}m</span>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
                  <div />
                  <button className="press" disabled={offsetBusy} onClick={() => adjustOffset(5, 0)} style={{ height: 38, borderRadius: 14, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, fontWeight: 600 }}>North +5m</button>
                  <div />
                  <button className="press" disabled={offsetBusy} onClick={() => adjustOffset(0, -5)} style={{ height: 38, borderRadius: 14, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, fontWeight: 600 }}>West +5m</button>
                  <div style={{ height: 38, borderRadius: 14, background: 'var(--hh-accent-tint)', border: '1px solid var(--hh-accent-soft)', fontSize: 12, fontWeight: 600, color: 'var(--hh-accent)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Live offset</div>
                  <button className="press" disabled={offsetBusy} onClick={() => adjustOffset(0, 5)} style={{ height: 38, borderRadius: 14, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, fontWeight: 600 }}>East +5m</button>
                  <div />
                  <button className="press" disabled={offsetBusy} onClick={() => adjustOffset(-5, 0)} style={{ height: 38, borderRadius: 14, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, fontWeight: 600 }}>South +5m</button>
                  <div />
                </div>
              </div>
            )}
            {visibleFamily.length === 0 && <div style={{fontSize: 13, color: 'var(--hh-ink-mute)'}}>No people found.</div>}
          </>
        )}
        {/* Fences list — hide when draw mode is active */}
        {mode === 'fences' && drawState === 'idle' && !editingFence && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
              <div className="hh-serif" style={{ fontSize: 18 }}>Geofences</div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                <button className="press" onClick={startDraw} style={{ fontSize: 12, color: 'var(--hh-accent)' }}>+ Add</button>
                <button className="press" onClick={fitToFamily} style={{ fontSize: 12, color: 'var(--hh-accent)', display: 'flex', alignItems: 'center', gap: 4 }}><Icon name="map" size={14}/>Fit all</button>
              </div>
            </div>
            {visibleFences.map((g, i) => (
              <div key={g.id} onClick={() => flyToFence(g)} className="press" style={{ display: 'flex', gap: 10, alignItems: 'center', padding: '8px 0', borderTop: i ? '1px solid var(--hh-line-soft)' : 'none', cursor: 'pointer', borderRadius: 8, background: selectedFence === g.id ? 'var(--hh-accent-tint)' : 'transparent' }}>
                <div style={{ width: 32, height: 32, borderRadius: 999, background: (g.color || '#3b82f6') + '33', border: `2px solid ${g.color || '#3b82f6'}`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="pin" size={14} color={g.color || '#3b82f6'}/>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{g.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{g.address || `${g.lat?.toFixed(4)}, ${g.lng?.toFixed(4)}`} · {g.radius}m</div>
                </div>
                <button
                  className="press"
                  onClick={(e) => { e.stopPropagation(); editFence(g); }}
                  style={{ width: 30, height: 30, borderRadius: 999, background: 'var(--hh-surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginRight: 4 }}
                  title="Edit"
                >
                  <Icon name="edit" size={14} color="var(--hh-ink-mute)"/>
                </button>
                <button
                  className="press"
                  onClick={(e) => { e.stopPropagation(); removeGeofence(g.id); }}
                  style={{ width: 30, height: 30, borderRadius: 999, background: 'var(--hh-surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
                  title="Delete"
                >
                  <Icon name="close" size={14} color="var(--hh-ink-mute)"/>
                </button>
              </div>
            ))}
            {visibleFences.length === 0 && <div style={{fontSize: 13, color: 'var(--hh-ink-mute)'}}>No geofences yet. Tap "+ Add" to create one.</div>}
          </>
        )}
        {/* Edit fence panel */}
        {mode === 'fences' && editingFence && !editReposition && (() => {
          const fence = geofences.find(g => g.id === editingFence);
          if (!fence) return null;
          return (
            <div style={{ padding: '2px 0 6px' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
                <div className="hh-serif" style={{ fontSize: 16 }}>Edit geofence</div>
                <button onClick={cancelEdit} className="press" style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>✕ Close</button>
              </div>

              {/* Name */}
              <input
                value={editDraft.name}
                onChange={e => setEditDraft(d => ({ ...d, name: e.target.value }))}
                placeholder="Zone name"
                style={{
                  width: '100%', height: 40, borderRadius: 12,
                  border: '1.5px solid var(--hh-line-soft)',
                  background: 'var(--hh-surface-2)',
                  padding: '0 14px', fontSize: 14, color: 'var(--hh-ink)',
                  boxSizing: 'border-box', marginBottom: 10,
                }}
              />

              {/* Radius slider */}
              <div style={{ marginBottom: 10 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4, fontSize: 12 }}>
                  <span style={{ color: 'var(--hh-ink-soft)' }}>Radius</span>
                  <span style={{ fontWeight: 600, color: editDraft.color }}>{editDraft.radius} m</span>
                </div>
                <input
                  type="range" min="5" max="2000" step="5"
                  value={editDraft.radius}
                  onChange={e => setEditDraft(d => ({ ...d, radius: Number(e.target.value) }))}
                  style={{ width: '100%', accentColor: editDraft.color, display: 'block' }}
                />
              </div>

              {/* Color picker */}
              <div style={{ display: 'flex', gap: 8, marginBottom: 14, flexWrap: 'wrap' }}>
                {['#C9562E','#6E8662','#5F7E91','#C99A2E','#7A4F6B','#3b82f6'].map(c => (
                  <button key={c} onClick={() => setEditDraft(d => ({ ...d, color: c }))} style={{
                    width: 26, height: 26, borderRadius: '50%', background: c,
                    border: editDraft.color === c ? '3px solid var(--hh-ink)' : '2px solid transparent',
                    boxShadow: editDraft.color === c ? '0 0 0 2px var(--hh-surface)' : 'none',
                    flexShrink: 0,
                  }}/>
                ))}
              </div>

              {/* Notify toggle */}
              <button
                onClick={() => setEditDraft(d => ({ ...d, notify: !d.notify }))}
                className="press"
                style={{
                  display: 'flex', alignItems: 'center', gap: 8,
                  width: '100%', padding: '8px 12px', borderRadius: 12, marginBottom: 10,
                  background: editDraft.notify ? 'var(--hh-accent-tint)' : 'var(--hh-surface-2)',
                  border: `1.5px solid ${editDraft.notify ? 'var(--hh-accent)' : 'var(--hh-line-soft)'}`,
                  fontSize: 13, color: 'var(--hh-ink)',
                }}
              >
                <Icon name="bell" size={15} color={editDraft.notify ? 'var(--hh-accent)' : 'var(--hh-ink-mute)'}/>
                <span style={{ flex: 1, textAlign: 'left' }}>{editDraft.notify ? 'Notifications on' : 'Notifications off'}</span>
                <span style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{editDraft.notify ? 'Tap to mute' : 'Tap to enable'}</span>
              </button>

              {/* Action buttons */}
              <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
                <button
                  onClick={startEditReposition}
                  className="press"
                  style={{ flex: 1, height: 40, borderRadius: 14, background: 'var(--hh-surface-2)', fontSize: 13, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}
                >
                  <Icon name="pin" size={14}/> Reposition
                </button>
                <button
                  onClick={saveEdit}
                  className="press"
                  style={{ flex: 2, height: 40, borderRadius: 14, background: editDraft.color, color: '#fff', fontSize: 14, fontWeight: 600 }}
                >
                  Save changes
                </button>
              </div>

              {/* Delete */}
              {!confirmDelete ? (
                <button
                  onClick={() => setConfirmDelete(true)}
                  className="press"
                  style={{ width: '100%', height: 36, borderRadius: 12, background: 'transparent', fontSize: 12, color: 'var(--hh-ink-mute)', border: '1px solid var(--hh-line-soft)' }}
                >
                  Delete this geofence
                </button>
              ) : (
                <div style={{ display: 'flex', gap: 8 }}>
                  <button
                    onClick={() => setConfirmDelete(false)}
                    className="press"
                    style={{ flex: 1, height: 36, borderRadius: 12, background: 'var(--hh-surface-2)', fontSize: 12 }}
                  >Cancel</button>
                  <button
                    onClick={doDeleteFence}
                    className="press"
                    style={{ flex: 1, height: 36, borderRadius: 12, background: '#d44', color: '#fff', fontSize: 12, fontWeight: 600 }}
                  >Confirm delete</button>
                </div>
              )}
            </div>
          );
        })()}
        {/* Edit repositioning panel — shown when crosshair is active for an existing fence */}
        {mode === 'fences' && editingFence && editReposition && (
          <div style={{ padding: '14px 16px 20px' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
              <div>
                <div className="hh-serif" style={{ fontSize: 15 }}>Move geofence</div>
                <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 1 }}>Pan the map to reposition</div>
              </div>
              <button onClick={() => { editNewPosition.current = null; setEditReposition(false); setDrawState('idle'); mapRef.current?.getSource('preview')?.setData({ type: 'FeatureCollection', features: [] }); mapRef.current?.getSource('center-dot')?.setData({ type: 'FeatureCollection', features: [] }); }} className="press" style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>Cancel</button>
            </div>
            <button
              onClick={() => {
                // Capture current map center as the new fence position
                if (mapRef.current) {
                  const c = mapRef.current.getCenter();
                  editNewPosition.current = [c.lng, c.lat];
                }
                setEditReposition(false);
                setDrawState('idle');
                mapRef.current?.getSource('preview')?.setData({ type: 'FeatureCollection', features: [] });
                mapRef.current?.getSource('center-dot')?.setData({ type: 'FeatureCollection', features: [] });
              }}
              className="press"
              style={{ width: '100%', height: 42, borderRadius: 14, background: editDraft.color, color: '#fff', fontSize: 14, fontWeight: 600 }}
            >
              Confirm new position
            </button>
          </div>
        )}
        {mode === 'history' && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 10 }}>
              <div className="hh-serif" style={{ fontSize: 18 }}>Location logs</div>
              <div style={{ display: 'flex', gap: 6 }}>
                {[1, 7, 30].map(days => (
                  <button key={days} onClick={() => setHistoryDays(days)} className="press" style={{ height: 30, padding: '0 12px', borderRadius: 999, background: historyDays === days ? 'var(--hh-ink)' : 'var(--hh-surface-2)', color: historyDays === days ? 'var(--hh-bg)' : 'var(--hh-ink-soft)', fontSize: 11, fontWeight: 600 }}>{days}d</button>
                ))}
              </div>
            </div>
            <div className="hh-hscroll hh-scroll" style={{ paddingBottom: 8 }}>
              {family.filter(f => f.tracker_id).map(f => (
                <Chip key={f.id} active={selectedMember === f.id} onClick={() => setSelectedMember(f.id)}>{f.name}</Chip>
              ))}
            </div>
            {historyLoading && <div style={{ fontSize: 13, color: 'var(--hh-ink-mute)', paddingTop: 6 }}>Loading history…</div>}
            {!historyLoading && historyEntries.map((entry, i) => {
              const timestamp = entry.receivedAt || (entry.tst ? new Date(entry.tst * 1000).toISOString() : null);
              const dateText = timestamp ? new Date(timestamp).toLocaleString() : 'Unknown time';
              return (
                <div key={`${entry.user || selectedTrackerId}-${entry.tst || i}`} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', padding: '10px 0', borderTop: i ? '1px solid var(--hh-line-soft)' : 'none' }}>
                  <div style={{ width: 34, height: 34, borderRadius: 12, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                    <Icon name="route" size={16} color="var(--hh-accent)"/>
                  </div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 13, fontWeight: 600 }}>{selectedMemberObj?.name || entry.user || 'Tracked user'}</div>
                    <div style={{ fontSize: 12, color: 'var(--hh-ink-soft)', marginTop: 2 }}>{Number(entry.lat).toFixed(5)}, {Number(entry.lon).toFixed(5)}</div>
                    <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 3 }}>
                      Accuracy {entry.acc != null ? `${Math.round(entry.acc)}m` : '—'} · {entry.source || 'tracker'}
                    </div>
                  </div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', textAlign: 'right', minWidth: 88 }} className="hh-mono">{dateText}</div>
                </div>
              );
            })}
            {!historyLoading && historyEntries.length === 0 && <div style={{fontSize: 13, color: 'var(--hh-ink-mute)'}}>No tracker history for this period.</div>}
          </>
        )}
      </div>}
    </div>
  );
}

window.MapScreen = MapScreen;
