sudo bash -c 'cat >/tmp/ecz-setup-only.sh << "EOF"
#!/usr/bin/env bash
# ECZ Setup-Only: wizard (:1234) + hotspot + captive injectie (laat :80 met rust)
set -euo pipefail
LOGFILE="/var/log/ecz-setup-only.log"
exec > >(tee -a "$LOGFILE") 2>&1
export DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}"

# ---- Instellingen ----
WIZ_ZIP_URL="${WORKDIR_URL:-https://repo.easycomp.cloud/public_access/ECZ-BirdNET-Pi-WatchHouse/ecz-watchhouse-workdir.zip}"
WIZ_DIR="/opt/ecz/birdnet-wizard"
CADDYFILE="/etc/caddy/Caddyfile"
HOTSPOT_SSID="${HOTSPOT_SSID:-ECZ-BIRDNET-PI-SETUP}"
NFT_RULES="/etc/nftables.d/ecz-captive.nft"
NFT_UNIT="/etc/systemd/system/ecz-captive-nft.service"
WIZ_UNIT="/etc/systemd/system/ecz-setup-wizard.service"

log(){ echo -e "[+] $*"; }
warn(){ echo -e "[!] $*"; }
die(){ echo -e "[✗] $*"; exit 1; }

require_birdnet_ready(){
  command -v caddy >/dev/null || die "Caddy ontbreekt — run eerst de BirdNET-Pi installer en reboot."
  local code; code="$(curl -fs -o /dev/null -w "%{http_code}" http://127.0.0.1:80/ || true)"
  [[ "$code" = 2* || "$code" = 3* ]] || die "Poort 80 reageert niet (HTTP $code). BirdNET-Pi nog niet klaar?"
}

detect_wdev(){
  local w
  w="$(iw dev 2>/dev/null | awk '"'"'$1=="Interface"{print $2}'"'"' | grep -E "^(ap0|uap0|wlan0|wlan1)$" | head -n1 || true)"
  [ -n "$w" ] || w="$(iw dev 2>/dev/null | awk '"'"'$1=="Interface"{print $2; exit}'"'"' || true)"
  echo "$w"
}

# ---- 0) Preflight ----
require_birdnet_ready
dpkg --configure -a || true
apt-get -f install -y || true
apt-get update -y
apt-get install -y network-manager python3 python3-pip rsync unzip nftables curl ca-certificates

# ---- 1) Wizard deploy (alleen :1234) ----
log "Deploy wizard → $WIZ_DIR"
mkdir -p "$WIZ_DIR"
TMP="$(mktemp -d)"
curl -fL "$WIZ_ZIP_URL" -o "$TMP/payload.zip"
unzip -q "$TMP/payload.zip" -d "$TMP/unpacked"
if [[ -d "$TMP/unpacked/wizard" ]]; then SRC="$TMP/unpacked/wizard"; else SRC="$(find "$TMP/unpacked" -maxdepth 2 -type d -name wizard -print -quit)"; fi
[[ -n "${SRC:-}" ]] || SRC="$TMP/unpacked"
rsync -a --delete "$SRC"/ "$WIZ_DIR"/

# Optionele padfixes als ze in de bron staan
sed -i "s#/home/shaady/BirdNET-Pi/birdnet.conf#/home/${SUDO_USER:-${USER}}/BirdNET-Pi/birdnet.conf#g" "$WIZ_DIR/app.py" 2>/dev/null || true
sed -i "s#/home/shaady#/home/${SUDO_USER:-${USER}}#g" "$WIZ_DIR/app.py" 2>/dev/null || true

log "Python deps (Flask)…"
pip3 install --break-system-packages Flask==3.0.3 Jinja2 itsdangerous Werkzeug || pip3 install Flask==3.0.3 Jinja2 itsdangerous Werkzeug

log "Wizard systemd-service aanzetten (root, :1234)"
cat > "$WIZ_UNIT" <<EOFU
[Unit]
Description=ECZ BirdNET-Pi Setup Wizard (Flask, :1234)
After=network-online.target
Wants=network-online.target
[Service]
User=root
Group=root
WorkingDirectory=$WIZ_DIR
ExecStart=/usr/bin/python3 $WIZ_DIR/app.py --host 0.0.0.0 --port 1234
Restart=on-failure
RestartSec=3
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
EOFU
systemctl daemon-reload
systemctl enable --now ecz-setup-wizard

# ---- 2) Hotspot via NetworkManager (OPEN AP) ----
log "Hotspot configureren (OPEN) via NetworkManager…"
WDEV="$(detect_wdev)"; [[ -n "$WDEV" ]] || die "Geen Wi-Fi interface gevonden."
rfkill unblock wifi || true
nmcli radio wifi on || true
ip link set "$WDEV" up || true

# Verwijder oude profielen met dezelfde naam (voorkom WEP erfenis)
for UUID in $(nmcli -g UUID,NAME con show | awk -F: -v s="$HOTSPOT_SSID" '"'"'$2==s{print $1}'"'"'); do nmcli con delete "$UUID" || true; done

# Nieuw OPEN AP-profiel (ipv4 shared, ipv6 ignore)
nmcli con add type wifi ifname "$WDEV" con-name "$HOTSPOT_SSID" ssid "$HOTSPOT_SSID" \
  802-11-wireless.mode ap 802-11-wireless.band bg 802-11-wireless.channel 6 \
  ipv4.method shared ipv6.method ignore connection.autoconnect yes

# Forceer géén security-sectie (anders WEP/secrets-errors)
nmcli con mod "$HOTSPOT_SSID" -802-11-wireless-security 2>/dev/null || true
nmcli con mod "$HOTSPOT_SSID" -wifi-sec 2>/dev/null || true
systemctl restart NetworkManager
sleep 2
nmcli connection reload || true
nmcli con up "$HOTSPOT_SSID" ifname "$WDEV" || warn "Hotspot niet direct actief; probeer zo opnieuw."

# Wacht op IP (shared ⇒ meestal 10.42.0.1)
for i in $(seq 1 25); do
  HIP="$(ip -4 addr show "$WDEV" | awk '"'"'/inet /{print $2}'"'"' | cut -d/ -f1)"
  [[ -n "${HIP:-}" ]] && break
  sleep 1
done
[[ -n "${HIP:-}" ]] && log "Hotspot IP: $HIP" || warn "Geen hotspot IP gezien (verwacht 10.42.x.x)."

# ---- 3) Caddy: alléén captive-probe paden injecteren in bestaand :80-blok ----
log "Caddy captive-probes injecteren (bestaand :80-blok; niets anders aanpassen)…"
[[ -f "$CADDYFILE" ]] || die "Caddyfile niet gevonden ($CADDYFILE)."
cp -a "$CADDYFILE" "${CADDYFILE}.bak.$(date +%s)"
grep -qE "^[[:space:]]*:80[[:space:]]*{" "$CADDYFILE" || die "Geen bestaand :80-blok in Caddyfile — BirdNET-Pi config afw? Stop."

if grep -q "ECZ captive probes" "$CADDYFILE"; then
  sed -i "s#redir http://[^ ]\\+:1234#redir http://${HIP:-10.42.0.1}:1234#g" "$CADDYFILE"
else
  awk -v ip="${HIP:-10.42.0.1}" '"'"'
    BEGIN{in80=0; inserted=0}
    /^\s*:80\s*\{/ { if(!inserted) in80=1 }
    { print
      if(in80 && /^\}\s*$/ && !inserted){
        print "  # ECZ captive probes → wizard (alleen probe-paden)"
        print "  @captive path /generate_204 /hotspot-detect.html /connecttest.txt /ncsi.txt /success.txt"
        print "  handle @captive {"
        print "    redir http://" ip ":1234 302"
        print "  }"
        inserted=1; in80=0
      }
    }'"'"' "$CADDYFILE" > "${CADDYFILE}.new"
  mv "${CADDYFILE}.new" "$CADDYFILE"
fi
caddy validate --config "$CADDYFILE" && systemctl reload caddy || {
  warn "Caddy validatie faalde — rollback."
  cp "${CADDYFILE}.bak."* "$CADDYFILE" 2>/dev/null || true
  systemctl restart caddy
}

# ---- 4) nftables NAT: HTTP vanaf hotspot → :1234 ----
log "nftables captive-redirect activeren (alle HTTP via $WDEV naar :1234)…"
systemctl enable --now nftables
mkdir -p /etc/nftables.d
cat > "$NFT_RULES" <<EOFR
table inet ecz_captive {
  chain prerouting {
    type nat hook prerouting priority -100; policy accept;
    iifname "$WDEV" tcp dport 80 redirect to :1234
  }
}
EOFR
cat > "$NFT_UNIT" <<'EOFU'
[Unit]
Description=ECZ captive HTTP redirect (hotspot -> :1234)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/nft -f /etc/nftables.d/ecz-captive.nft
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOFU
systemctl daemon-reload
systemctl enable --now ecz-captive-nft

# ---- 5) Smoketest ----
log "Smoketest…"
H80="$(curl -fs -o /dev/null -w "%{http_code}" http://127.0.0.1:80/ || true)"
H12="$(curl -fs -o /dev/null -w "%{http_code}" http://127.0.0.1:1234/ || true)"
systemctl is-active --quiet caddy && echo "[OK] caddy actief" || die "caddy inactief"
systemctl is-active --quiet ecz-setup-wizard && echo "[OK] wizard actief" || die "wizard-service inactief"
[[ "$H80" = 2* || "$H80" = 3* ]] || die "poort 80 geen 2xx/3xx ($H80)"
[[ "$H12" = 2* || "$H12" = 3* ]] || die "poort 1234 geen 2xx/3xx ($H12)"
sudo nft list ruleset | grep -A2 "table inet ecz_captive" >/dev/null || die "nftables captive rules niet geladen"

echo
echo "✅ Klaar. Hotspot: ${HOTSPOT_SSID} (open). Captive → wizard:  http://${HIP:-10.42.0.1}:1234"
echo "ℹ️  BirdNET-Pi blijft op poort 80 (onaangetast)."
EOF
chmod +x /tmp/ecz-setup-only.sh
bash /tmp/ecz-setup-only.sh'
