#!/usr/bin/env bash

_bashers_python() {
  local script_dir candidate
  script_dir="$(dirname "$0")"
  
  candidate="$script_dir/python3"
  if [[ -x "$candidate" ]]; then
    echo "$candidate"
    return 0
  fi
  
  candidate="$script_dir/python"
  if [[ -x "$candidate" ]]; then
    echo "$candidate"
    return 0
  fi
  
  command -v python3 2>/dev/null || command -v python 2>/dev/null
}

_bashers_require_python() {
  if [[ -z "$(_bashers_python)" ]]; then
    echo "bashers: python is required but not found on PATH" >&2
    exit 127
  fi
}

_bashers_pkg_dir() {
  if [[ -n "${BASHERS_DIR-}" ]]; then
    echo "$BASHERS_DIR"
    return 0
  fi

  local python_bin="$(_bashers_python)"
  if [[ -n "$python_bin" ]]; then
    local pkg_dir
    pkg_dir="$("$python_bin" - <<'PY' 2>/dev/null
import importlib.resources as resources
try:
    print(resources.files("bashers"))
except (ModuleNotFoundError, ImportError):
    exit(1)
PY
)"
    if [[ -n "$pkg_dir" && -d "$pkg_dir" ]]; then
      echo "$pkg_dir"
      return 0
    fi
  fi

  return 1
}

_bashers_normalize_pkg_dir() {
  local candidate="$1"
  if [[ -z "$candidate" ]]; then
    return 1
  fi
  if [[ -f "$candidate/__init__.py" ]]; then
    echo "$candidate"
    return 0
  fi
  if [[ -f "$candidate/bashers/__init__.py" ]]; then
    echo "$candidate/bashers"
    return 0
  fi
  echo "$candidate"
}

_bashers_version() {
  local python_bin="$(_bashers_python)"
  if [[ -z "$python_bin" ]]; then
    echo "unknown"
    return 0
  fi
  "$python_bin" - <<'PY'
import importlib.metadata as metadata
try:
    print(metadata.version("bashers"))
except metadata.PackageNotFoundError:
    print("unknown")
PY
}

_bashers_list_commands() {
  local pkg_dir="$1"
  local rel base
  declare -A counts=()
  declare -A rels=()

  while IFS= read -r path; do
    rel="${path#"$pkg_dir"/}"
    _bashers_is_visible "$rel" || continue
    base="$(basename "$rel")"
    counts["$base"]=$((counts["$base"] + 1))
    rels["$rel"]=1
  done < <(find "$pkg_dir" -type f)

  for rel in "${!rels[@]}"; do
    base="$(basename "$rel")"
    if [[ ${counts["$base"]} -gt 1 ]]; then
      echo "$rel"
    else
      echo "$base"
    fi
  done | sort -u
}

_bashers_install_completion() {
  [[ -n "${BASHERS_NO_AUTO_COMPLETION-}" ]] && return 0
  [[ -z "${BASH_VERSION-}" ]] && return 0

  local pkg_dir="$1"
  local completion_src="$pkg_dir/completions/bashers.bash"
  [[ ! -f "$completion_src" ]] && return 0

  local xdg_dir="${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions"
  local legacy_dir="$HOME/.bash_completion.d"
  local target=""

  if [[ -d "$xdg_dir" || ! -d "$legacy_dir" ]]; then
    target="$xdg_dir/bashers"
  else
    target="$legacy_dir/bashers"
  fi

  if [[ ! -f "$target" ]]; then
    mkdir -p "$(dirname "$target")" 2>/dev/null || return 0
    cp "$completion_src" "$target" 2>/dev/null || return 0
  fi
}

_bashers_find_lib() {
  local pkg_dir=""
  pkg_dir="$(_bashers_pkg_dir)"
  pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"
  if [[ -n "$pkg_dir" && -f "$pkg_dir/_bashers_lib" ]]; then
    echo "$pkg_dir/_bashers_lib"
    return 0
  fi

  local dir
  if [[ -z "${BASH_SOURCE[0]-}" ]]; then
    return 1
  fi
  dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || return 1
  [[ -z "$dir" ]] && return 1
  while [[ "$dir" != "/" && -n "$dir" ]]; do
    if [[ -f "$dir/_bashers_lib" ]]; then
      echo "$dir/_bashers_lib"
      return 0
    fi
    local parent="$(dirname "$dir")"
    [[ "$parent" == "$dir" ]] && break
    dir="$parent"
  done
  return 1
}

if [[ -z "${_BASHERS_LIB_LOADED-}" ]]; then
  _bashers_lib="$(_bashers_find_lib)"
  if [[ -n "$_bashers_lib" && -f "$_bashers_lib" ]]; then
    source "$_bashers_lib"
    _BASHERS_LIB_LOADED=1
  fi
fi

_bashers_require_python

print_help() {
  local pkg_dir="$1"
  _bashers_color_init
  _bashers_print_title "Bashers - Bash command helpers"
  echo ""
  _bashers_print_usage "bashers <COMMAND> [ARGS]"
  echo ""
  _bashers_print_section "Commands"
  _bashers_print_kv "help" "Display help for bashers or a command"
  _bashers_print_kv "completion" "Print bash completion script"
  _bashers_print_kv "version" "Print bashers version"
  if [[ -d "$pkg_dir" ]]; then
    declare -A descriptions=(
      [gh]="Git home: checkout default branch, pull, fetch all"
      [setup]="Install project dependencies (uv/poetry)"
      [show]="List installed packages (uv/poetry)"
      [update]="Update dependencies (uv/poetry)"
    )
    mapfile -t commands < <(_bashers_list_commands "$pkg_dir")
    for cmd in "${commands[@]}"; do
      if [[ -n "${descriptions[$cmd]-}" ]]; then
        _bashers_print_kv "$cmd" "${descriptions[$cmd]}"
      else
        printf "  %s%s%s\n" "$BASHERS_CYAN" "$cmd" "$BASHERS_RESET"
      fi
    done
  fi
  echo ""
  echo "Use ${BASHERS_BOLD}bashers <command> --help${BASHERS_RESET} for more details."
}

_bashers_is_visible() {
  local rel="$1"
  [[ -z "$rel" ]] && return 1
  [[ "$rel" == completions/* ]] && return 1
  [[ "$rel" == utils/* ]] && return 1
  [[ "$rel" == "bashers" ]] && return 1
  [[ "$rel" == __* || "$rel" == .* || "$rel" == _* ]] && return 1
  [[ "$rel" == */__* || "$rel" == */.* || "$rel" == */_* ]] && return 1
  [[ "$rel" == *.py || "$rel" == *.pyc ]] && return 1
  return 0
}

if [[ $# -eq 0 ]]; then
  pkg_dir="$(_bashers_pkg_dir)"
  pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"
  print_help "$pkg_dir"
  exit 0
fi

command="$1"
shift

case "$command" in
  help|-h|--help)
    pkg_dir="$(_bashers_pkg_dir)"
    pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"
    print_help "$pkg_dir"
    exit 0
    ;;
  --version|-V)
    echo "bashers $(_bashers_version)"
    exit 0
    ;;
  version)
    echo "bashers $(_bashers_version)"
    exit 0
    ;;
  completion)
    pkg_dir="$(_bashers_pkg_dir)"
    pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"
    if [[ -f "$pkg_dir/completions/bashers.bash" ]]; then
      cat "$pkg_dir/completions/bashers.bash"
      exit 0
    fi
    echo "bashers: completion script not found" >&2
    exit 1
    ;;
  _commands)
    pkg_dir="$(_bashers_pkg_dir)"
    pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"
    _bashers_list_commands "$pkg_dir"
    exit 0
    ;;
esac

pkg_dir="$(_bashers_pkg_dir)"
pkg_dir="$(_bashers_normalize_pkg_dir "$pkg_dir")"

if [[ -z "$pkg_dir" || ! -d "$pkg_dir" ]]; then
  echo "bashers: unable to locate package data" >&2
  python_bin="$(_bashers_python)"
  if [[ -n "$python_bin" ]]; then
    if command -v pyenv >/dev/null 2>&1; then
      echo "  bashers is not installed in the current Python version" >&2
      echo "  Install with: pip install bashers" >&2
      echo "  Or switch to a Python version that has bashers installed" >&2
    else
      echo "  Install with: pip install bashers" >&2
    fi
  else
    echo "  Python not found on PATH" >&2
  fi
  exit 127
fi

_bashers_install_completion "$pkg_dir"

script_path=""
if [[ "$command" == */* ]]; then
  candidate="$pkg_dir/$command"
  [[ -f "$candidate" ]] && script_path="$candidate"
else
  matches=()
  while IFS= read -r candidate; do
    rel="${candidate#"$pkg_dir"/}"
    _bashers_is_visible "$rel" || continue
    matches+=("$candidate")
  done < <(find "$pkg_dir" -type f -name "$command")
  if [[ ${#matches[@]} -gt 1 ]]; then
    echo "Command '$command' is ambiguous. Use a path:" >&2
    for match in "${matches[@]}"; do
      echo "  ${match#"$pkg_dir"/}" >&2
    done
    exit 2
  fi
  [[ ${#matches[@]} -eq 1 ]] && script_path="${matches[0]}"
fi

if [[ -n "$script_path" && -f "$script_path" ]]; then
  script_name="$(basename "$script_path")"
  if [[ "$script_name" == "update" || "$script_name" == "setup" ]]; then
    export NO_SPINNER=1
  fi
  _bashers_color_init
  if grep -qE "^[[:space:]]*${script_name}[[:space:]]*\\(\\)[[:space:]]*\\{" "$script_path"; then
    _bashers_run bash -c "source \"$script_path\" && $script_name \"\$@\"" -- "$@"
    exit $?
  fi
  _bashers_run "$script_path" "$@"
  exit $?
fi

echo "Command '$command' not found. Use 'bashers help' for available commands."
exit 1
