#!/usr/bin/env bash
set -euo pipefail

# ============================================================
# photo_sanad.sh
# ------------------------------------------------------------
# ONE command to run everything:
#   ./photo_sanad.sh
#
# What it does:
# 1) Activates the camera env (py3.10) and starts the Core direct camera service in background
# 2) Activates gemini (py3.11) and runs Gemini/voice_sanad.py in foreground
# 3) Sets PulseAudio default sink/source (optional)
# 4) Sets PYTHONPATH for unitree_sdk2_python (so unitree_sdk2py imports work)
# 5) On exit, stops the direct camera server
# ============================================================

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
DEFAULT_BASE_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
BASE_DIR="${BASE_DIR:-$DEFAULT_BASE_DIR}"
PY_FILE="$BASE_DIR/Gemini/voice_sanad.py"
RUN_USER="${SUDO_USER:-${USER:-$(id -un)}}"
RUN_USER_HOME="$(getent passwd "$RUN_USER" 2>/dev/null | cut -d: -f6 || true)"
if [[ -z "${RUN_USER_HOME:-}" ]]; then
  RUN_USER_HOME="$HOME"
fi
RUN_USER_ID="$(id -u "$RUN_USER" 2>/dev/null || true)"
export HOME="$RUN_USER_HOME"
if [[ -n "${RUN_USER_ID:-}" ]] && [[ -d "/run/user/$RUN_USER_ID" ]]; then
  export XDG_RUNTIME_DIR="/run/user/$RUN_USER_ID"
  if [[ -S "$XDG_RUNTIME_DIR/pulse/native" ]]; then
    export PULSE_SERVER="unix:$XDG_RUNTIME_DIR/pulse/native"
  fi
fi

# conda
CONDA_SH="${CONDA_SH:-$RUN_USER_HOME/miniconda3/etc/profile.d/conda.sh}"
ENV_TELE="teleimager"   # Python 3.10 camera env (pyrealsense2)
ENV_GEM="gemini"        # Python 3.11
SDK_PY_PATH="${SDK_PY_PATH:-$RUN_USER_HOME/unitree_sdk2_python}"
DIRECT_CAMERA_PORT="${DIRECT_CAMERA_PORT:-8091}"
DIRECT_CAMERA_HOST="${DIRECT_CAMERA_HOST:-127.0.0.1}"
DIRECT_CAMERA_SOURCE="${DIRECT_CAMERA_SOURCE:-realsense}"
DIRECT_CAMERA_SCRIPT="${DIRECT_CAMERA_SCRIPT:-$BASE_DIR/Core/direct_camera_service.py}"
LEGACY_DIRECT_CAMERA_SCRIPT="$BASE_DIR/Scripts/direct_camera_samples_server.py"

# Optional: choose your camera (if needed)
# export CAMERA_DEVICE=/dev/video2
# export PHOTO_PREFIX=photo
export CAMERA_DEVICE="${CAMERA_DEVICE:-/dev/video0}"
export PHOTO_PREFIX="${PHOTO_PREFIX:-photo}"

# RealSense fix/sudo behavior
SUDO_ENABLE_FIX="${SUDO_ENABLE_FIX:-1}"          # 1=cache sudo so /api/fix can run
SUDO_PROMPT_ON_START="${SUDO_PROMPT_ON_START:-0}"  # 1=allow interactive sudo prompt at startup
AUTO_FIX_ON_START="${AUTO_FIX_ON_START:-0}"      # 1=run fix script once on startup
SUDO_KEEPALIVE_INTERVAL="${SUDO_KEEPALIVE_INTERVAL:-60}"
FIX_SCRIPT="${FIX_SCRIPT:-$BASE_DIR/Scripts/fix_realsense_usb.sh}"
SUDO_KEEPALIVE_PID=""
LOG_DIR="${LOG_DIR:-$BASE_DIR/Logs}"
PHOTO_SERVER_PORT="${PHOTO_SERVER_PORT:-8080}"
PRE_KILL_OLD="${PRE_KILL_OLD:-1}"   # 1=stop stale sanad/camera services from previous runs
FREE_PORT_BEFORE_START="${FREE_PORT_BEFORE_START:-1}"  # 1=kill listeners on PHOTO_SERVER_PORT
ALLOW_EXISTING_PORT_SERVER="${ALLOW_EXISTING_PORT_SERVER:-0}"  # 1=allow attaching to an already-running gallery server

# PulseAudio device names (change if needed)
SINK="${SINK:-alsa_output.usb-Anker_PowerConf_A3321-DEV-SN1-01.analog-stereo}"
SOURCE="${SOURCE:-alsa_input.usb-Anker_PowerConf_A3321-DEV-SN1-01.mono-fallback}"

# ALSA plugin fix (helps conda envs stop spamming ALSA errors)
if [[ -d "/usr/lib/aarch64-linux-gnu/alsa-lib" ]]; then
  export ALSA_PLUGIN_DIR="/usr/lib/aarch64-linux-gnu/alsa-lib"
elif [[ -d "/usr/lib/alsa-lib" ]]; then
  export ALSA_PLUGIN_DIR="/usr/lib/alsa-lib"
fi
if [[ -f "/usr/share/alsa/alsa.conf" ]]; then
  export ALSA_CONFIG_PATH="/usr/share/alsa/alsa.conf"
fi
export ALSA_LOG_LEVEL=0

echo "📁 Base dir: $BASE_DIR"
echo "👤 Runtime user: $RUN_USER"
echo "🏠 Runtime home: $RUN_USER_HOME"
cd "$BASE_DIR"

# ---------- logging dir ----------
if ! mkdir -p "$LOG_DIR" >/dev/null 2>&1; then
  LOG_DIR="$HOME/.ai_photographer_logs"
  mkdir -p "$LOG_DIR"
fi
if ! touch "$LOG_DIR/.write_test" >/dev/null 2>&1; then
  LOG_DIR="$HOME/.ai_photographer_logs"
  mkdir -p "$LOG_DIR"
  touch "$LOG_DIR/.write_test" >/dev/null 2>&1 || true
fi
rm -f "$LOG_DIR/.write_test" >/dev/null 2>&1 || true
export AI_PHOTOGRAPHER_LOG_DIR="$LOG_DIR"

# ---------- stale-process cleanup ----------
show_port_owner() {
  local port="$1"
  if command -v ss >/dev/null 2>&1; then
    # shellcheck disable=SC2016
    ss -ltnp 2>/dev/null | awk -v p=":$port" '$4 ~ p {print $0}' || true
  fi
}

start_sudo_keepalive() {
  (
    while true; do
      sleep "$SUDO_KEEPALIVE_INTERVAL"
      sudo -n true >/dev/null 2>&1 || exit 0
    done
  ) &
  SUDO_KEEPALIVE_PID=$!
  echo "✅ sudo cached (keepalive PID=$SUDO_KEEPALIVE_PID)"
}

setup_sudo_cache() {
  if [[ "$SUDO_ENABLE_FIX" != "1" ]]; then
    return 0
  fi

  if ! command -v sudo >/dev/null 2>&1; then
    echo "⚠️ sudo not found; /api/fix cannot run privileged fixes."
    return 0
  fi

  if sudo -n true >/dev/null 2>&1; then
    echo "🔐 sudo credentials already cached."
    start_sudo_keepalive
    return 0
  fi

  if [[ "$SUDO_PROMPT_ON_START" == "1" && -t 0 ]]; then
    echo "🔐 Preparing sudo for RealSense fix endpoint..."
    if sudo -v; then
      start_sudo_keepalive
    else
      echo "⚠️ sudo auth failed; /api/fix may require manual terminal command."
    fi
  else
    echo "⚠️ sudo not cached. Use SUDO_PROMPT_ON_START=1 to allow startup prompt."
  fi
}

get_port_pids() {
  local port="$1"
  {
    if command -v lsof >/dev/null 2>&1; then
      lsof -t -iTCP:"$port" -sTCP:LISTEN -Pn 2>/dev/null || true
    fi
    if command -v ss >/dev/null 2>&1; then
      ss -ltnp 2>/dev/null \
        | awk -v p=":$port" '$4 ~ p {print $0}' \
        | sed -n 's/.*pid=\([0-9][0-9]*\).*/\1/p' || true
    fi
    if command -v fuser >/dev/null 2>&1; then
      fuser -n tcp "$port" 2>/dev/null | tr ' ' '\n' || true
    fi
  } | sed '/^[[:space:]]*$/d' | sort -u
}

get_pid_cmdline() {
  local pid="$1"
  ps -o args= -p "$pid" 2>/dev/null || true
}

kill_one_pid() {
  local pid="$1"
  local signal="${2:-TERM}"
  local pgid=""
  [[ -z "${pid:-}" ]] && return 0

  if ! kill "-$signal" "$pid" >/dev/null 2>&1; then
    sudo -n kill "-$signal" "$pid" >/dev/null 2>&1 || true
  fi

  pgid="$(ps -o pgid= -p "$pid" 2>/dev/null | tr -d ' ' || true)"
  if [[ -n "${pgid:-}" ]]; then
    if ! kill "-$signal" "--" "-$pgid" >/dev/null 2>&1; then
      sudo -n kill "-$signal" "--" "-$pgid" >/dev/null 2>&1 || true
    fi
  fi
}

kill_port_owner() {
  local port="$1"
  local pids pid attempt
  pids="$(get_port_pids "$port" || true)"
  [[ -z "${pids:-}" ]] && return 0

  echo "🛑 Attempting to free port $port (PID(s): $(echo "$pids" | tr '\n' ' '))"
  for attempt in 1 2 3; do
    while IFS= read -r pid; do
      [[ -z "${pid:-}" ]] && continue
      if [[ "$attempt" -lt 3 ]]; then
        kill_one_pid "$pid" TERM
      else
        kill_one_pid "$pid" KILL
      fi
    done <<< "$pids"
    sleep 1
    pids="$(get_port_pids "$port" || true)"
    [[ -z "${pids:-}" ]] && return 0
    if [[ "$attempt" -eq 2 ]]; then
      echo "⚠️ Port $port still busy, sending SIGKILL..."
    fi
  done
}

report_port_owners() {
  local port="$1"
  local pids pid cmd
  pids="$(get_port_pids "$port" || true)"
  [[ -z "${pids:-}" ]] && return 0
  while IFS= read -r pid; do
    [[ -z "${pid:-}" ]] && continue
    cmd="$(get_pid_cmdline "$pid")"
    echo "   - PID $pid: ${cmd:-<unknown>}"
  done <<< "$pids"
}

stop_stale_processes() {
  echo "🧽 Checking stale processes..."
  local stopped=0

  # Previous Sanad app instances from same project copy
  if pgrep -f "$BASE_DIR/Gemini/voice_sanad.py" >/dev/null 2>&1; then
    echo "🛑 Stopping previous voice_sanad.py processes..."
    pkill -f "$BASE_DIR/Gemini/voice_sanad.py" >/dev/null 2>&1 || sudo -n pkill -f "$BASE_DIR/Gemini/voice_sanad.py" >/dev/null 2>&1 || true
    stopped=1
  fi
  # Legacy pre-restructure path support
  if pgrep -f "$BASE_DIR/voice_sanad.py" >/dev/null 2>&1; then
    echo "🛑 Stopping previous legacy voice_sanad.py processes..."
    pkill -f "$BASE_DIR/voice_sanad.py" >/dev/null 2>&1 || sudo -n pkill -f "$BASE_DIR/voice_sanad.py" >/dev/null 2>&1 || true
    stopped=1
  fi

# Previous direct camera servers
  if pgrep -f "$DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1; then
    echo "🛑 Stopping previous direct camera service processes..."
    pkill -f "$DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1 || sudo -n pkill -f "$DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1 || true
    stopped=1
  fi
  if [[ "$DIRECT_CAMERA_SCRIPT" != "$LEGACY_DIRECT_CAMERA_SCRIPT" ]] && pgrep -f "$LEGACY_DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1; then
    echo "🛑 Stopping previous legacy direct_camera_samples_server.py processes..."
    pkill -f "$LEGACY_DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1 || sudo -n pkill -f "$LEGACY_DIRECT_CAMERA_SCRIPT" >/dev/null 2>&1 || true
    stopped=1
  fi

  # Give OS a moment to release sockets/resources.
  if [[ "$stopped" -eq 1 ]]; then
    sleep 1
  fi
}

# Try to cache sudo early so stale cleanup can stop root-owned leftovers.
setup_sudo_cache

if [[ "$PRE_KILL_OLD" == "1" ]]; then
  stop_stale_processes
fi

PORT_OWNER="$(show_port_owner "$PHOTO_SERVER_PORT" || true)"
if [[ -n "${PORT_OWNER:-}" ]]; then
  echo "⚠️ Port $PHOTO_SERVER_PORT currently in use:"
  echo "$PORT_OWNER"
fi

# ---------- conda init ----------
if [[ ! -f "$CONDA_SH" ]]; then
  echo "❌ conda.sh not found: $CONDA_SH"
  exit 1
fi
# shellcheck disable=SC1090
source "$CONDA_SH"

# ---------- time sync wait ----------
echo "⏰ Checking system time..."
while [ "$(date +%Y)" -lt 2025 ]; do
  echo "⏳ Waiting for time sync... $(date)"
  sleep 2
done
echo "✅ Time synced: $(date)"

# ---------- PulseAudio defaults (optional) ----------
pick_pactl_device() {
  local kind="$1"
  local requested="$2"
  local current=""
  local names=""
  local chosen=""

  if [[ "$kind" == "sink" ]]; then
    current="$(pactl info 2>/dev/null | sed -n 's/^Default Sink: //p' | head -n1)"
    names="$(pactl list short sinks 2>/dev/null | awk '{print $2}')"
  else
    current="$(pactl info 2>/dev/null | sed -n 's/^Default Source: //p' | head -n1)"
    names="$(pactl list short sources 2>/dev/null | awk '{print $2}')"
  fi

  if [[ -n "${requested:-}" ]] && echo "$names" | grep -Fxq "$requested"; then
    chosen="$requested"
  elif [[ -n "${current:-}" ]] && echo "$names" | grep -Fxq "$current"; then
    chosen="$current"
  else
    chosen="$(echo "$names" | grep -Ei 'anker|powerconf|usb' | head -n1 || true)"
    if [[ -z "${chosen:-}" ]]; then
      chosen="$(echo "$names" | head -n1 || true)"
    fi
  fi

  printf '%s' "$chosen"
}

if command -v pactl >/dev/null 2>&1; then
  echo "🔊 Checking audio server..."
  READY=0
  for _ in {1..20}; do
    if timeout 0.3s pactl info >/dev/null 2>&1; then
      READY=1
      break
    fi
    sleep 0.3
  done

  if [[ "$READY" -eq 1 ]]; then
    RESOLVED_SINK="$(pick_pactl_device sink "$SINK")"
    RESOLVED_SOURCE="$(pick_pactl_device source "$SOURCE")"

    if [[ -n "${RESOLVED_SINK:-}" ]]; then
      if [[ "$RESOLVED_SINK" != "$SINK" ]]; then
        echo "⚠️ Requested speaker not found. Using → $RESOLVED_SINK"
      else
        echo "🎧 Setting default speaker → $RESOLVED_SINK"
      fi
      pactl set-default-sink "$RESOLVED_SINK" || true
    else
      echo "⚠️ No PulseAudio sink found. Continuing without speaker selection."
    fi

    if [[ -n "${RESOLVED_SOURCE:-}" ]]; then
      if [[ "$RESOLVED_SOURCE" != "$SOURCE" ]]; then
        echo "⚠️ Requested microphone not found. Using → $RESOLVED_SOURCE"
      else
        echo "🎤 Setting default microphone → $RESOLVED_SOURCE"
      fi
      pactl set-default-source "$RESOLVED_SOURCE" || true
    else
      echo "⚠️ No PulseAudio source found. Continuing without microphone selection."
    fi

    ACTIVE_SINK="$(pactl info 2>/dev/null | sed -n 's/^Default Sink: //p' | head -n1 || true)"
    ACTIVE_SOURCE="$(pactl info 2>/dev/null | sed -n 's/^Default Source: //p' | head -n1 || true)"
    [[ -n "${ACTIVE_SINK:-}" ]] && echo "🔈 Active speaker default: $ACTIVE_SINK"
    [[ -n "${ACTIVE_SOURCE:-}" ]] && echo "🎙️ Active microphone default: $ACTIVE_SOURCE"
  else
    echo "⚠️ PulseAudio/PipeWire not ready. Continuing anyway."
  fi
else
  echo "⚠️ pactl not found. Skipping audio defaults."
fi

# ---------- paths check ----------
if [[ ! -f "$PY_FILE" ]]; then
  echo "❌ voice_sanad.py not found: $PY_FILE"
  exit 1
fi

# ---------- startup mode / runtime profile ----------
# Primary config lives in Data/Settings/config.json. Keep legacy Data/config.json
# and Scripts/config.json fallbacks so older robot copies can still boot during migrations.
MODE_FROM_CFG="$(python - <<'PY'
import json
from pathlib import Path
p = Path("Data/Settings/config.json")
legacy_candidates = [Path("Data/config.json"), Path("Scripts/config.json")]
if not p.exists():
    for legacy in legacy_candidates:
        if legacy.exists():
            p = legacy
            break
mode = "manual"
try:
    if p.exists():
        d = json.loads(p.read_text(encoding="utf-8"))
        mode_block = d.get("mode") or {}
        mode = str(mode_block.get("default_mode", mode_block.get("current_mode", "manual"))).strip().lower()
except Exception:
    mode = "manual"
if mode == "command":
    mode = "ai"
try:
    if p.exists():
        d = json.loads(p.read_text(encoding="utf-8"))
        mode_block = d.get("mode") or {}
        mode_block["current_mode"] = mode
        d["mode"] = mode_block
        p.write_text(json.dumps(d, indent=2), encoding="utf-8")
except Exception:
    pass
print(mode if mode in ("manual", "ai") else "manual")
PY
)"
echo "✅ Runtime mode reset to default: $MODE_FROM_CFG"

PHOTO_OUTPUT_DIR="$(python - <<'PY'
import json
from pathlib import Path
base = Path(".").resolve()
p = Path("Data/Settings/config.json")
legacy_candidates = [Path("Data/config.json"), Path("Scripts/config.json")]
if not p.exists():
    for legacy in legacy_candidates:
        if legacy.exists():
            p = legacy
            break
value = "AI_Photographer/photos/Captures"
try:
    if p.exists():
        d = json.loads(p.read_text(encoding="utf-8"))
        paths = d.get("paths") or {}
        value = str(paths.get("photos_dir", value) or value).strip()
except Exception:
    pass
target = Path(value).expanduser()
if not target.is_absolute():
    parts = target.parts
    if parts and parts[0] == base.name:
        target = (base.parent / target).resolve()
    else:
        target = (base / target).resolve()
print(target)
PY
)"
echo "🗂️ Capture output dir: $PHOTO_OUTPUT_DIR"

if [[ -z "${MANUAL_LEAN_RUNTIME:-}" ]]; then
  if [[ "$MODE_FROM_CFG" == "manual" ]]; then
    export MANUAL_LEAN_RUNTIME=0
  else
    export MANUAL_LEAN_RUNTIME=0
  fi
fi
if [[ "$MODE_FROM_CFG" == "manual" && "${MANUAL_LEAN_RUNTIME}" == "1" ]]; then
  echo "🪶 Manual lean runtime enabled: direct camera/DDS/replay startup will be skipped."
fi

# ---------- start direct camera server (py3.10) ----------
TELE_PID=""
TELE_LOG="$LOG_DIR/direct_camera.log"
if [[ "$MODE_FROM_CFG" == "manual" && "${MANUAL_LEAN_RUNTIME}" == "1" ]]; then
  echo "📷 Skipping direct camera startup for lean manual runtime."
else
  kill_port_owner "$DIRECT_CAMERA_PORT"
  echo "🐍 Activating camera env: $ENV_TELE"
  conda activate "$ENV_TELE"

  echo "🐍 camera env python: $(which python)"
  python -c "import sys; print('✅ camera env sys.executable:', sys.executable); print('✅ camera env sys.version:', sys.version.split()[0])"

  echo "📷 Starting direct camera server in background..."
  python "$DIRECT_CAMERA_SCRIPT" \
    --camera "$DIRECT_CAMERA_SOURCE" \
    --host "$DIRECT_CAMERA_HOST" \
    --port "$DIRECT_CAMERA_PORT" \
    --samples-dir "$PHOTO_OUTPUT_DIR" \
    --capture-prefix "$PHOTO_PREFIX" \
    --capture-ext jpg >"$TELE_LOG" 2>&1 &
  TELE_PID=$!
  echo "✅ direct camera PID=$TELE_PID  log=$TELE_LOG"
fi

cleanup() {
  echo ""
  echo "🧹 Cleaning up..."
  if [[ -n "${SUDO_KEEPALIVE_PID:-}" ]] && kill -0 "$SUDO_KEEPALIVE_PID" >/dev/null 2>&1; then
    echo "🛑 Stopping sudo keepalive PID=$SUDO_KEEPALIVE_PID"
    kill "$SUDO_KEEPALIVE_PID" >/dev/null 2>&1 || true
    wait "$SUDO_KEEPALIVE_PID" >/dev/null 2>&1 || true
  fi
  if [[ -n "${TELE_PID:-}" ]] && kill -0 "$TELE_PID" >/dev/null 2>&1; then
    echo "🛑 Stopping direct camera server PID=$TELE_PID"
    kill "$TELE_PID" >/dev/null 2>&1 || true
    wait "$TELE_PID" >/dev/null 2>&1 || true
  fi
  echo "✅ Done."
}
trap cleanup EXIT INT TERM

# Give server time to start
if [[ -n "${TELE_PID:-}" ]]; then
  sleep 2
fi

# ---------- run sanad (py3.11) ----------
echo "🐍 Activating gemini env: $ENV_GEM"
conda activate "$ENV_GEM"

echo "🐍 gemini python: $(which python)"
python -c "import sys; print('✅ gemini sys.executable:', sys.executable); print('✅ gemini sys.version:', sys.version.split()[0])"

# ---------- autonomous enable policy ----------
# If AUTONOMOUS_ENABLE is not explicitly provided, derive from startup default mode:
# - full runtime -> arm autonomous services so AI mode can start live without restart
# - lean manual runtime -> keep disabled
if [[ -z "${AUTONOMOUS_ENABLE:-}" ]]; then
  if [[ "$MODE_FROM_CFG" == "manual" && "${MANUAL_LEAN_RUNTIME}" == "1" ]]; then
    export AUTONOMOUS_ENABLE=0
  else
    export AUTONOMOUS_ENABLE=1
  fi
  echo "🤖 AUTONOMOUS_ENABLE auto-set to $AUTONOMOUS_ENABLE (mode=$MODE_FROM_CFG, lean_manual=${MANUAL_LEAN_RUNTIME})"
else
  echo "🤖 AUTONOMOUS_ENABLE preset to $AUTONOMOUS_ENABLE"
fi

# Ensure unitree_sdk2py can import using the local project modules.
export PYTHONPATH="$SDK_PY_PATH:${BASE_DIR}:${PYTHONPATH:-}"
echo "🔧 Using local AI_Photographer modules"
export DIRECT_CAMERA_ENABLED="${DIRECT_CAMERA_ENABLED:-1}"
export DIRECT_CAMERA_SERVER_URL="${DIRECT_CAMERA_SERVER_URL:-http://$DIRECT_CAMERA_HOST:$DIRECT_CAMERA_PORT}"

echo "🔧 PYTHONPATH=$PYTHONPATH"
echo "📷 DIRECT_CAMERA_SERVER_URL=$DIRECT_CAMERA_SERVER_URL"
echo "🔧 ALSA_PLUGIN_DIR=${ALSA_PLUGIN_DIR:-"(not set)"}"
echo "🔧 ALSA_CONFIG_PATH=${ALSA_CONFIG_PATH:-"(not set)"}"
echo "🎥 CAMERA_DEVICE=$CAMERA_DEVICE"
echo "🖼️ PHOTO_PREFIX=$PHOTO_PREFIX"
echo "🔧 FIX_SCRIPT=$FIX_SCRIPT"
echo "🪵 LOG_DIR=$LOG_DIR"

# sudo cache is handled earlier by setup_sudo_cache.

if [[ "$AUTO_FIX_ON_START" == "1" ]]; then
  if [[ -f "$FIX_SCRIPT" ]]; then
    echo "🛠️ Running RealSense fix on startup..."
    if sudo bash "$FIX_SCRIPT" --fix; then
      echo "✅ RealSense fix completed."
    else
      echo "⚠️ RealSense fix failed; continuing startup."
    fi
  else
    echo "⚠️ AUTO_FIX_ON_START=1 but fix script not found: $FIX_SCRIPT"
  fi
fi

# Final port cleanup right before launching main app (after sudo caching)
if [[ "$FREE_PORT_BEFORE_START" == "1" ]]; then
  kill_port_owner "$PHOTO_SERVER_PORT"
fi
PORT_OWNER="$(show_port_owner "$PHOTO_SERVER_PORT" || true)"
if [[ -n "${PORT_OWNER:-}" ]]; then
  echo "⚠️ Port $PHOTO_SERVER_PORT remains in use:"
  echo "$PORT_OWNER"
  report_port_owners "$PHOTO_SERVER_PORT"
  if [[ "$ALLOW_EXISTING_PORT_SERVER" != "1" ]]; then
    echo "❌ Refusing to continue while a stale server still owns port $PHOTO_SERVER_PORT."
    echo "   Set ALLOW_EXISTING_PORT_SERVER=1 only if you intentionally want to attach to the existing server."
    exit 1
  fi
fi

echo "🚀 Starting Sanad AI_Photographer..."
# Run in foreground (so trap cleanup runs when process exits)
python "$PY_FILE"
