#!/usr/bin/env bash

update() {
  local pkg="${1-}"

  if [[ "$pkg" == "-h" || "$pkg" == "--help" ]]; then
    cat <<'EOF'
Usage: update [package]

Update Python dependencies in the current project.

If [package] is provided, updates just that package (with fuzzy matching).
Works with uv or poetry projects.
EOF
    return 0
  fi

  [[ -n "$pkg" && "$pkg" == -* ]] && { echo "[update]: usage: update [package]" >&2; return 2; }
  _need() { command -v "$1" >/dev/null 2>&1 || { echo "[update]: $1 not on PATH" >&2; return 127; }; }
  _has_project() { [[ -f pyproject.toml ]] && grep -qE '^\[project\]' pyproject.toml; }
  _has_poetry() { [[ -f pyproject.toml ]] && grep -qE '^\[tool\.poetry\]' pyproject.toml; }
  _has_prerelease() {
    [[ -f pyproject.toml ]] && grep -qE '[0-9]+\.[0-9]+(\.[0-9]+)?[a-zA-Z]|\.(a|b|rc|dev|pre|alpha|beta)[0-9]' pyproject.toml
  }

  local packages_cmd=""
  if [[ -f uv.lock ]] || _has_project; then
    _need uv || return $?
    packages_cmd="uv pip list 2>/dev/null | tail -n +3 | awk '{print \$1}'"
  elif [[ -f poetry.lock ]] || _has_poetry; then
    _need poetry || return $?
    packages_cmd="poetry show 2>/dev/null | grep -E '^name\s+:' | sed 's/^name\s*:\s*//'"
  else
    echo "[update]: no uv/poetry project found in $(pwd)" >&2
    return 2
  fi

  if [[ -n "$pkg" ]]; then
    local matches=$(eval "$packages_cmd" | grep -iE "$pkg")
    local count=$(echo "$matches" | grep -c . || echo "0")
    [[ "$count" -eq 0 ]] && { echo "[update]: no packages found matching '$pkg'" >&2; return 1; }
    [[ "$count" -gt 1 ]] && { _need fzf || return 127; pkg=$(echo "$matches" | fzf --prompt="Package> "); }
    [[ -z "$pkg" ]] && return 1
  fi

  if [[ -f uv.lock ]] || _has_project; then
    local prerelease_flag=""
    _has_prerelease && prerelease_flag="--prerelease allow"
    [[ -z "$pkg" ]] && uv lock --upgrade $prerelease_flag || uv lock --upgrade-package "$pkg" $prerelease_flag
    uv sync --all-extras
  else
    local prerelease_flag=""
    _has_prerelease && prerelease_flag="--allow-prereleases"
    [[ -z "$pkg" ]] && poetry update $prerelease_flag || poetry update "$pkg" $prerelease_flag
  fi
  return $?
}
