#!/usr/bin/env bash
# hold your voice — install node (if needed) + @holdyourvoice/hyv
set -euo pipefail

HYV_PKG="@holdyourvoice/hyv@latest"
MIN_NODE_MAJOR=18
NODE_LTS="22.16.0"
ENSURE_NODE_ONLY=0

for arg in "$@"; do
  case "$arg" in
    --ensure-node-only) ENSURE_NODE_ONLY=1 ;;
  esac
done

log() { printf '  %s\n' "$*"; }
warn() { printf '  ! %s\n' "$*" >&2; }

node_major() {
  node -p "parseInt(process.versions.node.split('.')[0], 10)" 2>/dev/null || echo 0
}

node_ok() {
  command -v node >/dev/null 2>&1 || return 1
  [[ "$(node_major)" -ge "$MIN_NODE_MAJOR" ]]
}

refresh_path() {
  export PATH="/usr/local/bin:/opt/homebrew/bin:${HOME}/.local/share/fnm:${PATH}"
  hash -r 2>/dev/null || true
}

install_node_fnm() {
  export FNM_DIR="${FNM_DIR:-${HOME}/.local/share/fnm}"
  export FNM_VERSION="${FNM_VERSION:-v1.38.1}"
  mkdir -p "$FNM_DIR"
  if ! command -v fnm >/dev/null 2>&1; then
    log "installing fnm (user-level node manager)..."
    curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-no-use
  fi
  refresh_path
  if ! command -v fnm >/dev/null 2>&1 && [[ -x "${FNM_DIR}/fnm" ]]; then
    export PATH="${FNM_DIR}:${PATH}"
  fi
  command -v fnm >/dev/null 2>&1 || return 1
  eval "$(fnm env)"
  fnm install "$NODE_LTS"
  fnm default "$NODE_LTS"
  eval "$(fnm env)"
}

install_node_mac() {
  if command -v brew >/dev/null 2>&1; then
    log "installing node via homebrew..."
    brew install node
    refresh_path
    return 0
  fi
  if install_node_fnm; then
    refresh_path
    return 0
  fi
  local arch pkg
  arch="$(uname -m)"
  case "$arch" in
    arm64) pkg="node-v${NODE_LTS}.pkg" ;;
    x86_64) pkg="node-v${NODE_LTS}.pkg" ;;
    *) warn "unsupported mac architecture: $arch"; return 1 ;;
  esac
  local url="https://nodejs.org/dist/v${NODE_LTS}/${pkg}"
  local tmp="/tmp/hyv-node-v${NODE_LTS}.pkg"
  log "downloading node ${NODE_LTS}..."
  curl -fsSL "$url" -o "$tmp"
  log "installing node (may ask for your password)..."
  sudo installer -pkg "$tmp" -target /
  refresh_path
}

install_node_linux() {
  if install_node_fnm; then
    refresh_path
    return 0
  fi
  if command -v apt-get >/dev/null 2>&1; then
    log "installing node via apt (nodesource)..."
    curl -fsSL "https://deb.nodesource.com/setup_${NODE_LTS%%.*}.x" | sudo -E bash -
    sudo apt-get install -y nodejs
    refresh_path
    return 0
  fi
  if command -v dnf >/dev/null 2>&1; then
    log "installing node via dnf..."
    sudo dnf install -y nodejs npm
    refresh_path
    return 0
  fi
  warn "could not auto-install node on this linux distro — install node ${MIN_NODE_MAJOR}+ manually"
  return 1
}

install_node() {
  case "$(uname -s)" in
    Darwin) install_node_mac ;;
    Linux) install_node_linux ;;
    *)
      warn "unsupported platform for auto node install"
      return 1
      ;;
  esac
}

ensure_node() {
  refresh_path
  if node_ok; then
    log "node $(node -v) found"
    return 0
  fi
  log "node ${MIN_NODE_MAJOR}+ not found — installing automatically..."
  install_node
  refresh_path
  if node_ok; then
    log "node $(node -v) ready"
    return 0
  fi
  warn "node install finished but node is still not on PATH — open a new terminal and run this script again"
  return 1
}

install_hyv() {
  if ! command -v npm >/dev/null 2>&1; then
    warn "npm not found after node install"
    return 1
  fi
  log "installing hold your voice..."
  npm i -g "$HYV_PKG"
  refresh_path
  if command -v hyv >/dev/null 2>&1; then
    log "running hyv welcome..."
    hyv welcome
  else
    warn "hyv installed but not on PATH — open a new terminal and run: hyv welcome"
  fi
}

main() {
  printf '\nhold your voice — installer\n\n'
  ensure_node
  if [[ "$ENSURE_NODE_ONLY" -eq 1 ]]; then
    exit 0
  fi
  install_hyv
  printf '\n  ✓ done — hyv is ready\n\n'
}

main "$@"