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

EON_DIR="$HOME/.eon"
EON_REPO="Eon-Labs-Team/eon-cli"
EON_HTTPS_URL="https://github.com/${EON_REPO}.git"
EON_SSH_URL="git@github.com:${EON_REPO}.git"

check_node() {
  if ! command -v node &>/dev/null; then
    echo "✗ Node.js is not installed."
    echo "→ Install it from: https://nodejs.org/en/download"
    exit 1
  fi

  local version
  version=$(node -e "process.stdout.write(process.version.replace(/^v/, '').split('.')[0])")
  if [ "$version" -lt 20 ]; then
    echo "✗ Node.js 20+ is required (found v${version})."
    echo "→ Install the latest LTS from: https://nodejs.org/en/download"
    exit 1
  fi
}

check_git() {
  if ! command -v git &>/dev/null; then
    echo "✗ git is not installed."
    echo "→ Install it from: https://git-scm.com/downloads"
    exit 1
  fi
}

can_use_gh() {
  command -v gh &>/dev/null && gh auth status &>/dev/null
}

print_access_help() {
  echo ""
  echo "This repository is private. Configure one of these access methods:"
  echo "  1. GitHub CLI: gh auth login"
  echo "  2. Git over SSH: add an SSH key with access to ${EON_REPO}"
  echo "  3. Git over HTTPS: configure git credentials / a GitHub PAT"
  echo ""
  echo "If you already configured auth, verify that your GitHub user has permission to ${EON_REPO}."
}

print_git_failure() {
  local action="$1"
  local remote="$2"
  local output="$3"

  echo "✗ Could not ${action} eon from ${remote}."

  if [[ "$output" == *"Not possible to fast-forward, aborting."* ]] \
    || [[ "$output" == *"would be overwritten by merge"* ]] \
    || [[ "$output" == *"Your local changes to the following files would be overwritten"* ]]; then
    echo "→ Local changes in ${EON_DIR} are blocking the update."
    echo "→ Commit/stash/reset them, or remove ${EON_DIR} and reinstall."
    return
  fi

  if [[ "$output" == *"could not read Username"* ]] \
    || [[ "$output" == *"Authentication failed"* ]] \
    || [[ "$output" == *"terminal prompts disabled"* ]]; then
    echo "→ Git does not have credentials configured for this private repo."
    print_access_help
    return
  fi

  if [[ "$output" == *"Permission denied (publickey)"* ]]; then
    echo "→ Your SSH key is missing or does not have access to ${EON_REPO}."
    print_access_help
    return
  fi

  if [[ "$output" == *"Permission to "* ]] \
    || [[ "$output" == *"The requested URL returned error: 403"* ]]; then
    echo "→ Your current GitHub user does not have permission to access ${EON_REPO}."
    print_access_help
    return
  fi

  if [[ "$output" == *"Repository not found"* ]] \
    || [[ "$output" == *"The requested URL returned error: 404"* ]]; then
    echo "→ GitHub rejected access to ${EON_REPO}."
    echo "→ This usually means the repo is private and your current credentials do not have access."
    print_access_help
    return
  fi

  if [[ "$output" == *"Could not resolve host"* ]] \
    || [[ "$output" == *"Failed to connect to github.com"* ]] \
    || [[ "$output" == *"Connection timed out"* ]] \
    || [[ "$output" == *"Operation timed out"* ]]; then
    echo "→ Network error while contacting GitHub. Check your connection/VPN and try again."
    return
  fi

  echo "→ Git returned:"
  printf '%s\n' "$output" | tail -n 5
}

clone_with_git() {
  local ssh_output=""
  local https_output=""

  rm -rf "$EON_DIR"
  if ssh_output=$(GIT_SSH_COMMAND='ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new' git clone "$EON_SSH_URL" "$EON_DIR" 2>&1); then
    return 0
  fi

  rm -rf "$EON_DIR"
  if https_output=$(GIT_TERMINAL_PROMPT=0 git clone "$EON_HTTPS_URL" "$EON_DIR" 2>&1); then
    return 0
  fi

  rm -rf "$EON_DIR"
  echo "✗ Could not clone eon with git."

  if [[ -n "$ssh_output" ]]; then
    echo ""
    echo "SSH clone failed:"
    printf '%s\n' "$ssh_output" | tail -n 5
  fi

  if [[ -n "$https_output" ]]; then
    echo ""
    echo "HTTPS clone failed:"
    printf '%s\n' "$https_output" | tail -n 5
  fi

  if [[ "$ssh_output" == *"Permission denied (publickey)"* ]]; then
    echo ""
    echo "→ SSH is not configured or your SSH key does not have access to ${EON_REPO}."
  fi

  if [[ "$https_output" == *"could not read Username"* ]] \
    || [[ "$https_output" == *"Authentication failed"* ]] \
    || [[ "$https_output" == *"terminal prompts disabled"* ]]; then
    echo ""
    echo "→ HTTPS clone could not authenticate with GitHub."
  elif [[ "$https_output" == *"Permission to "* ]] \
    || [[ "$https_output" == *"Repository not found"* ]] \
    || [[ "$https_output" == *"The requested URL returned error: 403"* ]] \
    || [[ "$https_output" == *"The requested URL returned error: 404"* ]]; then
    echo ""
    echo "→ The current GitHub credentials do not have access to ${EON_REPO}."
  fi

  print_access_help
  exit 1
}

clone_or_pull() {
  local output=""
  local origin_url="origin"

  if [ -d "$EON_DIR/.git" ]; then
    echo "→ Updating eon..."
    origin_url=$(git -C "$EON_DIR" remote get-url origin 2>/dev/null || echo "origin")
    if output=$(GIT_TERMINAL_PROMPT=0 git -C "$EON_DIR" pull --ff-only 2>&1); then
      return
    fi

    print_git_failure "update" "$origin_url" "$output"
    exit 1
  fi

  echo "→ Installing eon..."
  rm -rf "$EON_DIR"

  if can_use_gh; then
    if gh repo clone "$EON_REPO" "$EON_DIR"; then
      return
    fi

    echo "→ GitHub CLI clone failed. Trying git clone..."
    clone_with_git
    return
  fi

  if command -v gh &>/dev/null; then
    echo "→ GitHub CLI is installed but not authenticated. Trying git clone..."
  else
    echo "→ GitHub CLI not found. Trying git clone..."
  fi

  clone_with_git
}

build_and_link() {
  echo "→ Installing dependencies..."
  npm --prefix "$EON_DIR" install --silent

  echo "→ Building..."
  npm --prefix "$EON_DIR" run build --silent

  echo "→ Linking binary..."
  (cd "$EON_DIR" && npm link)
}

check_node
check_git
clone_or_pull
build_and_link

echo "✓ eon installed. Run 'eon --help' to get started."
