#!/usr/bin/env bash

# =======================================================
# 1. BOOTSTRAPPER: PREFER ZSH, FALLBACK TO BASH
# =======================================================
if [ -z "${_PREFER_ZSH_BOOTSTRAPPED:-}" ]; then
    export _PREFER_ZSH_BOOTSTRAPPED=1
    
    # Only attempt to re-execute if $0 is an actual file on disk.
    # This prevents the 'can't open input file' error when running 
    # from memory via `bash -c "$(curl ...)"` or `zsh -c`.
    if [ -f "$0" ]; then
        if command -v zsh >/dev/null 2>&1; then
            exec zsh "$0" "$@"
        elif command -v bash >/dev/null 2>&1; then
            exec bash "$0" "$@"
        else
            echo "Error: Neither Zsh nor Bash is installed. Exiting."
            exit 1
        fi
    fi
fi

set -u

# =======================================================
# 2. SHELL NORMALIZATION
# =======================================================
PROFILE_FILE="$HOME/.zshrc"

if [ -n "${ZSH_VERSION:-}" ]; then
    # Zsh: Enable Bash-like word splitting for unquoted variables (menu input)
    setopt shwordsplit 2>/dev/null || true
    CURRENT_SHELL="zsh"
elif [ -n "${BASH_VERSION:-}" ]; then
    CURRENT_SHELL="bash"
else
    CURRENT_SHELL="sh"
fi

# =======================================================
# COLORS & LOGGING
# =======================================================
GREEN="\033[0;32m"
RED="\033[0;31m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
NC="\033[0m"

log()  { printf "${GREEN}▶ %s${NC}\n" "$*"; }
warn() { printf "${YELLOW}⚠ %s${NC}\n" "$*"; }
err()  { printf "${RED}✖ %s${NC}\n" "$*"; }
info() { printf "${BLUE}ℹ %s${NC}\n" "$*"; }

# =======================================================
# HELPERS & SYSTEM DETECTION
# =======================================================
require_cmd() { command -v "$1" >/dev/null 2>&1; }

add_to_path_config() {
    local label=$1
    local path_line=$2
    local target_file="${3:-$PROFILE_FILE}"
    
    if [[ -f "$target_file" ]]; then
        if ! grep -q "$label" "$target_file"; then
            printf "\n# %s\n%s\n" "$label" "$path_line" >> "$target_file"
            log "Added $label to $target_file"
        fi
    else
        printf "\n# %s\n%s\n" "$label" "$path_line" >> "$PROFILE_FILE"
        log "Added $label to shell profile ($PROFILE_FILE)."
    fi
    
    # Instantly evaluate the path line so the current script session 
    # can immediately use the newly installed tool in subsequent steps.
    eval "$path_line" 2>/dev/null || true
}

detect_os_arch() {
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64|amd64) SYS_ARCH="amd64"; MAC_ARCH="x86_64"; AWS_ARCH="x86_64" ;;
        aarch64|arm64) SYS_ARCH="arm64"; MAC_ARCH="arm64"; AWS_ARCH="aarch64" ;;
        *) err "Unsupported architecture: $ARCH"; exit 1 ;;
    esac

    if [[ "$OSTYPE" == "darwin"* ]]; then
        OS="macOS"
        OS_LOWER="darwin"
    elif grep -qi microsoft /proc/version 2>/dev/null; then
        OS="WSL"
        OS_LOWER="linux"
    elif [[ -f /etc/os-release ]]; then
        . /etc/os-release
        [[ "$ID" == "ubuntu" || "$ID_LIKE" == *"ubuntu"* ]] && OS="Ubuntu" || OS="Linux"
        OS_LOWER="linux"
    else
        OS="Unknown"
        OS_LOWER="unknown"
    fi
    log "Detected: $OS ($ARCH) running $CURRENT_SHELL"
}

detect_os_arch

# =======================================================
# CORE RUNTIMES & MANAGERS
# =======================================================

install_build_tools() {
    log "Installing Build Essentials & Core Dependencies..."
    case "$OS" in
        Ubuntu|WSL) sudo apt-get update && sudo apt-get install -y build-essential curl wget git jq unzip libssl-dev zlib1g-dev libffi-dev libsqlite3-dev ;;
        macOS) xcode-select --install || warn "Xcode tools already installed" ;;
        *) warn "Manual installation required for $OS." ;;
    esac
}

install_brew() {
    if require_cmd brew; then warn "Homebrew already installed"; return; fi
    log "Installing Homebrew from Official Source..."
    
    # Homebrew's installer specifically requires Bash execution, regardless of current shell
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
    if [[ "$OS_LOWER" == "linux" ]]; then
        add_to_path_config "HOMEBREW" 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"'
    elif [[ "$MAC_ARCH" == "arm64" ]]; then
        add_to_path_config "HOMEBREW" 'eval "$(/opt/homebrew/bin/brew shellenv)"'
    else
        add_to_path_config "HOMEBREW" 'eval "$(/usr/local/bin/brew shellenv)"'
    fi
}

install_nvm() {
    # 1. Temporarily disable 'unbound variable' strictness for NVM
    set +u 
    
    export NVM_DIR="$HOME/.nvm"
    
    if [ -d "$NVM_DIR" ]; then 
        warn "NVM is already installed."
    else
        log "Installing NVM via $CURRENT_SHELL..."
        curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | $CURRENT_SHELL
    fi
    
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    
    printf "\n${YELLOW}Which version of Node.js would you like to install?${NC}\n"
    printf "  1) LTS (Long Term Support - Recommended for stability)\n"
    printf "  2) Latest (Current features - Recommended for testing new APIs)\n"
    printf "  3) Skip installing Node.js right now\n"
    
    printf "Select (1/2/3): " 
    read node_choice

    case "$node_choice" in
        2) 
            log "Installing Latest Node.js..."
            nvm install node
            nvm alias default node
            nvm use node
            
            log "Disabling npm logs..."
            npm config set logs-max 0
            ;;
        3) 
            log "Skipping Node.js installation." 
            ;;
        *) 
            log "Installing Latest LTS Node.js..."
            nvm install --lts
            nvm alias default 'lts/*'
            nvm use --lts
            
            log "Disabling npm logs..."
            npm config set logs-max 0
            ;;
    esac

    # 2. Re-enable 'unbound variable' strictness for the rest of your script
    set -u
}

install_python() {
    if [[ "$OS" == "macOS" ]]; then
        log "Fetching latest stable Python version..."
        LATEST_PY=$(
            curl -fsSL --compressed https://www.python.org/downloads/ |
            sed -nE 's/.*Download Python ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' |
            head -1
        )
        if [[ -z "$LATEST_PY" ]]; then
            err "Could not detect the latest stable Python version from python.org."
            return 1
        fi

        log "Detected Stable Version: $LATEST_PY"
        log "Downloading official macOS package..."
        PKG_URL="https://www.python.org/ftp/python/${LATEST_PY}/python-${LATEST_PY}-macos11.pkg"
        curl -fsSL --compressed -o /tmp/python.pkg "$PKG_URL" || {
            err "Failed to download Python macOS package from $PKG_URL"
            return 1
        }
        
        log "Running installer..."
        sudo installer -pkg /tmp/python.pkg -target / || {
            err "Python macOS installer failed."
            rm -f /tmp/python.pkg
            return 1
        }
        rm /tmp/python.pkg
    else
        log "Installing precompiled Python from the official OS repository..."
        if require_cmd apt-get; then
            sudo apt-get update && \
                sudo apt-get install -y python3 python3-pip python3-venv
        elif require_cmd dnf; then
            sudo dnf install -y python3 python3-pip
        elif require_cmd zypper; then
            sudo zypper --non-interactive install python3 python3-pip
        elif require_cmd pacman; then
            sudo pacman -Sy --needed python python-pip
        elif require_cmd apk; then
            sudo apk add python3 py3-pip py3-virtualenv
        else
            err "No supported official OS package manager found for Python."
            return 1
        fi
    fi

    require_cmd python3 || { err "python3 was not installed successfully."; return 1; }
    python3 -m pip --version >/dev/null 2>&1 || {
        err "pip is unavailable for the installed Python."
        return 1
    }
    python3 -m venv --help >/dev/null 2>&1 || {
        err "venv is unavailable for the installed Python."
        return 1
    }

    log "$(python3 --version) installed with pip and venv support."
}

install_go() {
    log "Fetching latest Go version from official source..."
    LATEST_GO=$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -n 1) || {
        err "Could not determine the latest Go version."
        return 1
    }
    TAR_FILE="${LATEST_GO}.${OS_LOWER}-${SYS_ARCH}.tar.gz"

    if [[ -x /usr/local/go/bin/go ]] && [[ "$(/usr/local/go/bin/go version)" == "go version $LATEST_GO "* ]]; then
        warn "$LATEST_GO is already installed."
        add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"'
        return 0
    fi
    
    log "Downloading $TAR_FILE..."
    curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE" || {
        err "Failed to download $TAR_FILE."
        rm -f /tmp/go.tar.gz
        return 1
    }
    
    log "Installing to /usr/local/go..."
    if ! sudo rm -rf /usr/local/go || ! sudo tar -C /usr/local -xzf /tmp/go.tar.gz; then
        err "Go installation failed. Run this installer from an interactive terminal so sudo can authenticate."
        rm -f /tmp/go.tar.gz
        return 1
    fi
    rm -f /tmp/go.tar.gz
    add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"'
    log "$(/usr/local/go/bin/go version) installed successfully."
}

install_sdkman() {
    if [ -d "$HOME/.sdkman" ]; then warn "SDKMAN already exists"; return; fi
    
    # SDKMAN explicitly blocks macOS's default Bash 3.2. 
    # If we are trapped in Bash < 4, force the installer to use Zsh.
    if [[ "$CURRENT_SHELL" == "bash" && "${BASH_VERSINFO[0]:-0}" -lt 4 ]]; then
        log "Outdated Bash detected. Installing SDKMAN via Zsh..."
        curl -s "https://get.sdkman.io" | zsh
    else
        log "Installing SDKMAN via $CURRENT_SHELL..."
        curl -s "https://get.sdkman.io" | $CURRENT_SHELL
    fi
}

install_dotnet() {
    log "Installing .NET from official script..."
    curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL
    add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"'
}

install_android() {
    log "Installing Android SDK command-line tools..."

    if ! require_cmd unzip; then
        err "unzip is required. Please install 'Build Tools' (Option 1) first."
        return 1
    fi

    if [[ "$OS_LOWER" == "linux" && "$SYS_ARCH" != "amd64" ]]; then
        err "Google's Android command-line tools installer supports Linux x86_64 only."
        return 1
    fi

    ANDROID_HOME="$HOME/Android/Sdk"
    ANDROID_SDK_ROOT="$ANDROID_HOME"
    export ANDROID_HOME ANDROID_SDK_ROOT

    mkdir -p "$ANDROID_HOME/cmdline-tools"

    if [[ "$OS" == "macOS" ]]; then
        TOOLS_OS="mac"
    elif [[ "$OS_LOWER" == "linux" ]]; then
        TOOLS_OS="linux"
    else
        err "Android SDK installation is not supported for $OS."
        return 1
    fi

    log "Finding latest Android command-line tools from Google..."
    TOOLS_URL=$(curl -fsSL https://developer.android.com/studio \
        | grep -o "https://dl.google.com/android/repository/commandlinetools-${TOOLS_OS}-[0-9]*_latest.zip" \
        | head -1)

    if [[ -z "$TOOLS_URL" ]]; then
        err "Could not find the Android command-line tools download URL."
        return 1
    fi

    log "Downloading Android command-line tools..."
    rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip
    mkdir -p /tmp/android-cmdline-tools
    curl -fsSL -o /tmp/android-cmdline-tools.zip "$TOOLS_URL"
    unzip -q /tmp/android-cmdline-tools.zip -d /tmp/android-cmdline-tools

    rm -rf "$ANDROID_HOME/cmdline-tools/latest"
    mkdir -p "$ANDROID_HOME/cmdline-tools/latest"
    mv /tmp/android-cmdline-tools/cmdline-tools/* "$ANDROID_HOME/cmdline-tools/latest/"
    rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip

    SDKMANAGER="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
    if [[ ! -x "$SDKMANAGER" ]]; then
        err "sdkmanager was not installed correctly."
        return 1
    fi

    log "Accepting Android SDK licenses..."
    yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null || true

    log "Installing Android SDK packages..."
    "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \
        "cmdline-tools;latest" \
        "platform-tools" \
        "emulator" \
        "platforms;android-36" \
        "build-tools;36.0.0"

    add_to_path_config "ANDROID_SDK" 'export ANDROID_HOME="$HOME/Android/Sdk"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator"'

    log "Android SDK installation sequence finished!"
}

# =======================================================
# CLOUD & INFRASTRUCTURE
# =======================================================

install_docker() {
    log "Checking Docker status..."
    
    # 1. Install if missing
    if ! require_cmd docker; then
        log "Installing Docker from official source..."
        if [[ "$OS" == "macOS" ]]; then
            [[ "$SYS_ARCH" == "arm64" ]] && DOCKER_MAC_ARCH="arm64" || DOCKER_MAC_ARCH="amd64"
            DMG_URL="https://desktop.docker.com/mac/main/${DOCKER_MAC_ARCH}/Docker.dmg"
            curl -fsSL -o /tmp/Docker.dmg "$DMG_URL"
            hdiutil attach /tmp/Docker.dmg -nobrowse -mountpoint /Volumes/Docker
            sudo cp -a /Volumes/Docker/Docker.app /Applications/
            hdiutil detach /Volumes/Docker
            rm /tmp/Docker.dmg
            
            log "Starting Docker Desktop..."
            open /Applications/Docker.app
            log "Please complete the setup in the Docker Desktop UI."
        else
            curl -fsSL https://get.docker.com | sudo sh
        fi
    else
        warn "Docker is already installed. Enforcing permissions..."
    fi

    # 2. Aggressively enforce Linux permissions
    if [[ "$OS" != "macOS" ]]; then
        log "Applying strict Linux post-install actions..."
        
        # Ensure docker group exists and user is added
        sudo groupadd -f docker
        sudo usermod -aG docker "$USER"
        
        # Ensure services are enabled and running
        if command -v systemctl >/dev/null 2>&1; then
            sudo systemctl enable --now docker.service
            sudo systemctl enable --now docker.socket containerd.service 2>/dev/null || true
        elif [[ "$OS" == "WSL" ]]; then
            sudo service docker start
        fi

        # Give the system a second to generate the socket file
        sleep 2

        # Lock in ownership and permissions on the socket
        if [[ -S /var/run/docker.sock ]]; then
            log "Securing /var/run/docker.sock..."
            sudo chown root:docker /var/run/docker.sock
            sudo chmod 660 /var/run/docker.sock
        else
            warn "Docker socket not found. The service may have failed to start."
        fi

        log "Added $USER to the docker group and secured the socket."
    fi
}

install_portainer() {
    log "Installing Portainer CE..."

    if ! require_cmd docker; then
        err "Docker is required. Please install Docker (Option 9) first."
        return 1
    fi

    if ! docker info >/dev/null 2>&1; then
        err "Docker is installed but the daemon is not running. Start Docker, then retry Portainer."
        return 1
    fi

    if docker ps -a --format '{{.Names}}' | grep -Fxq portainer; then
        warn "Portainer container already exists."
        if ! docker ps --format '{{.Names}}' | grep -Fxq portainer; then
            log "Starting existing Portainer container..."
            docker start portainer
        fi
        log "Portainer is available at https://localhost:9443"
        return 0
    fi

    docker volume create portainer_data || {
        err "Failed to create the Portainer data volume."
        return 1
    }

    if ! docker run -d \
        -p 8000:8000 \
        -p 9443:9443 \
        --name portainer \
        --restart=always \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v portainer_data:/data \
        portainer/portainer-ce:sts; then
        err "Failed to start the Portainer container."
        return 1
    fi

    log "Portainer is available at https://localhost:9443"
}

install_aws() {
    if require_cmd aws; then warn "AWS CLI exists"; return; fi
    log "Installing AWS CLI directly from Amazon..."

    if [[ "$OS" == "macOS" ]]; then
        curl -fsSL -o /tmp/AWSCLIV2.pkg "https://awscli.amazonaws.com/AWSCLIV2.pkg"
        sudo installer -pkg /tmp/AWSCLIV2.pkg -target /
        rm /tmp/AWSCLIV2.pkg
    else
        if ! require_cmd unzip; then 
            err "unzip is required. Please install 'Build Tools' (Option 1) first."
            return 1
        fi
        curl -fsSL -o /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip"
        cd /tmp && unzip -q awscliv2.zip && sudo ./aws/install
        rm -rf /tmp/awscliv2.zip /tmp/aws
    fi
}

install_gcloud() {
    local gcloud_dir="/opt/google-cloud-sdk"

    if [[ -x "$gcloud_dir/bin/gcloud" ]]; then warn "Google Cloud CLI exists at $gcloud_dir"; return; fi
    log "Installing Google Cloud CLI to $gcloud_dir..."
    curl -fsSL https://sdk.cloud.google.com | sudo bash -s -- --disable-prompts --install-dir=/opt
    sudo chown -R "$(id -u):$(id -g)" "$gcloud_dir"
    
    if [[ "$CURRENT_SHELL" == "zsh" ]]; then
        add_to_path_config "GCLOUD" '[ -f "/opt/google-cloud-sdk/path.zsh.inc" ] && source "/opt/google-cloud-sdk/path.zsh.inc"'
    else
        add_to_path_config "GCLOUD" '[ -f "/opt/google-cloud-sdk/path.bash.inc" ] && source "/opt/google-cloud-sdk/path.bash.inc"'
    fi
}

install_firebase() {
    if require_cmd firebase; then warn "Firebase CLI exists"; return; fi
    log "Installing Firebase CLI via NPM to ensure ARM64 compatibility..."
    
    if ! require_cmd npm; then
        err "NPM not found. Please install NVM (Option 3) first."
        return 1
    fi
    
    npm install -g firebase-tools
}

# =======================================================
# DEV TOOLS & SECURITY
# =======================================================

install_gh() {
    if require_cmd gh; then warn "GitHub CLI exists"; return; fi
    log "Fetching latest GitHub CLI version..."
    LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}"
    
    curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz"
    tar -xzf /tmp/gh.tar.gz -C /tmp
    sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/
    sudo rm -rf "/tmp/${TAR_NAME}" /tmp/gh.tar.gz
}

install_infisical() {
    if require_cmd infisical; then warn "Infisical CLI exists"; return; fi
    log "Installing Infisical CLI via NPM..."
    
    if ! require_cmd npm; then 
        err "NPM not found. Please install NVM (Option 3) first."
        return 1
    fi
    
    npm install -g @infisical/cli
}

# =======================================================
# AI & AGENTIC TOOLS
# =======================================================

install_claude() { log "Installing Claude Code..."; curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; }

install_opencode() { log "Installing OpenCode..."; curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; }

install_codex() {
    log "Installing @openai/codex..."
    if ! require_cmd npm; then err "Node.js/NPM is required. Install NVM (3) first."; return 1; fi
    npm i -g @openai/codex
}

install_augment() {
    if require_cmd auggie; then warn "Augment Code CLI exists"; return; fi
    log "Installing Augment Code CLI (Auggie)..."
    if ! require_cmd npm; then err "Node.js 20+/NPM is required. Install NVM (3) first."; return 1; fi
    npm install -g @augmentcode/auggie
}

install_coderabbit() {
    if require_cmd coderabbit || require_cmd cr; then warn "CodeRabbit CLI exists"; return; fi
    log "Installing CodeRabbit CLI..."
    curl -fsSL https://cli.coderabbit.ai/install.sh | sh
}

update_all() {
    log "Updating all installed software from official sources..."

    if require_cmd apt-get; then
        sudo apt-get update && sudo apt-get install -y --only-upgrade \
            build-essential curl wget git jq unzip libssl-dev zlib1g-dev libffi-dev libsqlite3-dev \
            python3 python3-pip python3-venv
    elif require_cmd dnf; then
        sudo dnf upgrade -y python3 python3-pip
    elif require_cmd zypper; then
        sudo zypper --non-interactive update python3 python3-pip
    elif require_cmd pacman; then
        sudo pacman -Syu --noconfirm python python-pip
    elif require_cmd apk; then
        sudo apk upgrade
    fi

    if [[ "$OS" == "macOS" ]] && require_cmd python3; then
        install_python
    fi

    require_cmd brew && { brew update && brew upgrade; }

    if [[ -s "$HOME/.nvm/nvm.sh" ]]; then
        set +u
        export NVM_DIR="$HOME/.nvm"
        LATEST_NVM=$(curl -fsSL https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
        curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${LATEST_NVM}/install.sh" | PROFILE=/dev/null $CURRENT_SHELL
        \. "$NVM_DIR/nvm.sh"
        nvm install --lts --reinstall-packages-from=current
        nvm alias default 'lts/*'
        nvm use --lts
        set -u
    fi

    require_cmd go && install_go

    if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then
        set +u
        source "$HOME/.sdkman/bin/sdkman-init.sh"
        sdk selfupdate force
        sdk upgrade
        set -u
    fi

    if require_cmd dotnet; then
        curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL
    fi

    local sdkmanager="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}/cmdline-tools/latest/bin/sdkmanager"
    if [[ -x "$sdkmanager" ]]; then
        yes | "$sdkmanager" --licenses >/dev/null || true
        "$sdkmanager" --update
    fi

    if require_cmd docker; then
        if [[ "$OS" == "macOS" ]]; then
            docker desktop update || warn "Update Docker Desktop from its application menu."
        else
            curl -fsSL https://get.docker.com | sudo sh
        fi
    fi

    if require_cmd docker && docker ps -a --format '{{.Names}}' | grep -Fxq portainer; then
        log "Updating Portainer CE..."
        docker pull portainer/portainer-ce:sts && \
            docker stop portainer && \
            docker rm portainer && \
            docker run -d \
                -p 8000:8000 \
                -p 9443:9443 \
                --name portainer \
                --restart=always \
                -v /var/run/docker.sock:/var/run/docker.sock \
                -v portainer_data:/data \
                portainer/portainer-ce:sts
    fi

    if require_cmd aws; then
        if [[ "$OS" == "macOS" ]]; then
            curl -fsSL -o /tmp/AWSCLIV2.pkg https://awscli.amazonaws.com/AWSCLIV2.pkg && \
                sudo installer -pkg /tmp/AWSCLIV2.pkg -target /
            rm -f /tmp/AWSCLIV2.pkg
        elif require_cmd unzip; then
            curl -fsSL -o /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip" && \
                rm -rf /tmp/aws && unzip -q /tmp/awscliv2.zip -d /tmp && \
                sudo /tmp/aws/install --update
            rm -rf /tmp/aws /tmp/awscliv2.zip
        fi
    fi

    require_cmd gcloud && gcloud components update --quiet
    require_cmd firebase && npm install -g firebase-tools@latest

    if require_cmd gh; then
        log "Updating GitHub CLI..."
        LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
        TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}"
        curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz" && \
            tar -xzf /tmp/gh.tar.gz -C /tmp && \
            sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/
        sudo rm -rf "/tmp/${TAR_NAME}" /tmp/gh.tar.gz
    fi

    require_cmd infisical && npm install -g @infisical/cli@latest
    require_cmd claude && { curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; }
    require_cmd codex && npm install -g @openai/codex@latest
    require_cmd opencode && { curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; }
    require_cmd auggie && npm install -g @augmentcode/auggie@latest
    if require_cmd coderabbit || require_cmd cr; then
        curl -fsSL https://cli.coderabbit.ai/install.sh | sh
    fi

    log "Finished updating installed software. Review any warnings or errors above."
}

# =======================================================
# MENU LOGIC
# =======================================================
show_menu() {
    clear
    printf "${BLUE}==================================================${NC}\n"
    printf "${GREEN}    DEVELOPER ENVIRONMENT INSTALLER (Polyglot)    ${NC}\n"
    printf "${BLUE}==================================================${NC}\n"
    printf "${YELLOW}--- Essentials & Package Managers ---${NC}\n"
    printf "  1) Build Tools (GCC/Make/Git/Curl/Unzip)\n"
    printf "  2) Homebrew (Optional)\n"
    printf "${YELLOW}--- Languages & Runtimes ---${NC}\n"
    printf "  3) NVM + Node.js\n"
    printf "  4) Python 3\n"
    printf "  5) Go\n"
    printf "  6) SDKMAN (Java/Kotlin/Gradle)\n"
    printf "  7) .NET\n"
    printf "${YELLOW}--- Mobile Development ---${NC}\n"
    printf "  8) Android SDK (CLI + Platform Tools)\n"
    printf "${YELLOW}--- Containers & Infrastructure ---${NC}\n"
    printf "  9) Docker\n"
    printf " 13) Portainer (Docker UI)\n"
    printf "${YELLOW}--- Cloud & App Platforms ---${NC}\n"
    printf " 10) AWS CLI\n"
    printf " 11) Google Cloud CLI (gcloud)\n"
    printf " 12) Firebase CLI\n"
    printf "${YELLOW}--- Developer Productivity ---${NC}\n"
    printf " 14) GitHub CLI\n"
    printf "${YELLOW}--- Secrets & Security ---${NC}\n"
    printf " 15) Infisical CLI\n"
    printf "${YELLOW}--- AI & Agentic Tools ---${NC}\n"
    printf " 16) Claude Code CLI\n"
    printf " 17) OpenAI Codex CLI\n"
    printf " 18) OpenCode\n"
    printf " 20) Augment Code CLI (Auggie)\n"
    printf " 21) CodeRabbit CLI\n"
    printf "${BLUE}==================================================${NC}\n"
    printf " 19) Update All Installed Software\n"
    printf " 99) Quit & Refresh Shell\n"
    printf "${BLUE}==================================================${NC}\n"
}

while true; do
    show_menu
    
    # Bulletproof prompt for both Bash and Zsh
    printf "Select options (space-separated): "
    if ! read input; then
        printf "\n"
        warn "Input closed. Exiting installer."
        exit 0
    fi
    
    # Thanks to 'setopt shwordsplit' in Zsh, this behaves perfectly across both shells
    for choice in $input; do
        case "$choice" in
            1) install_build_tools ;;
            2) install_brew ;;
            3) install_nvm ;;
            4) install_python ;;
            5) install_go ;;
            6) install_sdkman ;;
            7) install_dotnet ;;
            8) install_android ;;
            9) install_docker ;;
           10) install_aws ;;
           11) install_gcloud ;;
           12) install_firebase ;;
           13) install_portainer ;;
           14) install_gh ;;
           15) install_infisical ;;
           16) install_claude ;;
           17) install_codex ;;
           18) install_opencode ;;
           19) update_all ;;
           20) install_augment ;;
           21) install_coderabbit ;;
           99) 
               log "Installation complete! Refreshing terminal environment..."
               
               # If on Linux, forcefully inherit the new docker group without needing a logout
               if [[ "$OS" != "macOS" ]] && command -v sg >/dev/null 2>&1; then
                   exec sg docker -c "exec ${SHELL:-zsh}"
               else
                   exec "${SHELL:-zsh}" 
               fi
               ;;
            *) warn "Option $choice not valid." ;;
        esac
    done
    
    printf "Press Enter to continue..." 
    read dummy || exit 0
done
