#!/bin/bash
set -Eeuo pipefail

# ============================================================
# Nginx 通用管理脚本
# 支持按检测结果进入安装、升级/覆盖安装、卸载、回滚等流程。
# 当前为管理脚本骨架，后续逐步补齐各动作实现。
# ============================================================

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

LOG_FILE="/tmp/nginx_manage_$(date +%Y%m%d_%H%M%S).log"

NGINX_FOUND=false
INSTALL_METHOD=""
NGINX_SBIN=""
NGINX_VERSION=""
NGINX_PREFIX=""
NGINX_CONF=""
NGINX_PID_PATH=""
BACKUP_DIR=""
BACKUPS=()
BUILD_DIR=""
TARGET_VERSION=""
OFFLINE_PACKAGE=""
DEFAULT_INSTALL_PREFIX="/usr/local/nginx"
CONFIGURE_MODULES="--user=nginx --group=nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-stream --with-stream_ssl_module --with-http_v2_module"
CONFIGURE_ARGS="--prefix=${DEFAULT_INSTALL_PREFIX} ${CONFIGURE_MODULES}"
SERVICE_MANAGER=""
ORIGINAL_SERVICE_MANAGER=""

cleanup() {
    if [ -n "${BUILD_DIR:-}" ] && [ -d "$BUILD_DIR" ]; then
        rm -rf "$BUILD_DIR"
    fi
}

on_error() {
    local line_no=$1
    local command=$2
    set +e
    err "脚本执行失败，行号: ${line_no}"
    err "失败命令: ${command}"
    err "操作日志: ${LOG_FILE}"
}

trap cleanup EXIT
trap 'on_error "$LINENO" "$BASH_COMMAND"' ERR

log() { echo -e "${GREEN}[INFO]${NC} $1" | tee -a "$LOG_FILE"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE"; }
err() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"; }
title() { echo -e "\n${CYAN}========== $1 ==========${NC}" | tee -a "$LOG_FILE"; }

prompt_read() {
    local var_name=$1
    local prompt=$2

    if ! read -rp "$prompt" "$var_name"; then
        echo ""
        log "stdin EOF detected, exit"
        exit 0
    fi
}

check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        err "此脚本需要 root 权限运行"
        exit 1
    fi
}

detect_nginx() {
    local verbose="${1:-true}"

    if [ "$verbose" = true ]; then
        title "检测 Nginx"
    fi

    NGINX_FOUND=false
    INSTALL_METHOD=""
    NGINX_SBIN=""
    NGINX_VERSION=""
    NGINX_PREFIX=""
    NGINX_CONF=""
    NGINX_PID_PATH=""
    ORIGINAL_SERVICE_MANAGER=""

    local host_sbin=""

    if command -v nginx &>/dev/null; then
        host_sbin=$(command -v nginx)
    fi

    if [ -z "$host_sbin" ]; then
        local running_pid
        running_pid=$(pgrep -x nginx 2>/dev/null | head -1 || true)
        if [ -n "$running_pid" ] && [ -f "/proc/$running_pid/exe" ]; then
            local cgroup_info
            cgroup_info=$(cat "/proc/$running_pid/cgroup" 2>/dev/null || true)
            if ! echo "$cgroup_info" | grep -qE 'docker|containerd'; then
                host_sbin=$(readlink -f "/proc/$running_pid/exe")
            fi
        fi
    fi

    if [ -n "$host_sbin" ] && [ -f "$host_sbin" ]; then
        NGINX_FOUND=true
        NGINX_SBIN=$(readlink -f "$host_sbin" 2>/dev/null || echo "$host_sbin")
        NGINX_VERSION=$("$NGINX_SBIN" -v 2>&1 | sed -n 's|.*nginx/\([0-9.]*\).*|\1|p')

        if command -v zypper &>/dev/null && command -v rpm &>/dev/null && rpm -qf "$NGINX_SBIN" &>/dev/null 2>&1; then
            INSTALL_METHOD="zypper"
        elif command -v rpm &>/dev/null && rpm -qf "$NGINX_SBIN" &>/dev/null; then
            if command -v dnf &>/dev/null; then INSTALL_METHOD="dnf"; else INSTALL_METHOD="yum"; fi
        elif command -v dpkg &>/dev/null && dpkg -S "$NGINX_SBIN" &>/dev/null 2>&1; then
            INSTALL_METHOD="apt"
        elif command -v apk &>/dev/null && apk info --who-owns "$NGINX_SBIN" &>/dev/null 2>&1; then
            INSTALL_METHOD="apk"
        else
            INSTALL_METHOD="source"
        fi

        read_nginx_info
        if [ "$verbose" = true ]; then
            print_nginx_info
        fi
    else
        NGINX_FOUND=false
        if [ "$verbose" = true ]; then
            warn "未检测到宿主机 Nginx"
        fi
    fi
}

read_nginx_info() {
    local v_output
    v_output=$("$NGINX_SBIN" -V 2>&1 || true)

    NGINX_PREFIX=$(echo "$v_output" | sed -n 's|.*--prefix=\([^ ]*\).*|\1|p')
    NGINX_PREFIX=${NGINX_PREFIX:-/etc/nginx}
    NGINX_CONF=$(echo "$v_output" | sed -n 's|.*--conf-path=\([^ ]*\).*|\1|p')
    NGINX_CONF=${NGINX_CONF:-$NGINX_PREFIX/conf/nginx.conf}
    NGINX_PID_PATH=$(echo "$v_output" | sed -n 's|.*--pid-path=\([^ ]*\).*|\1|p')
    NGINX_PID_PATH=${NGINX_PID_PATH:-$NGINX_PREFIX/logs/nginx.pid}
    local detected_args
    detected_args=$(echo "$v_output" | grep "configure arguments:" | sed 's/.*configure arguments: //')
    [ -n "$detected_args" ] && CONFIGURE_ARGS="$detected_args"

    if command -v systemctl &>/dev/null && systemctl is-active nginx &>/dev/null 2>&1; then
        ORIGINAL_SERVICE_MANAGER="systemd"
    else
        ORIGINAL_SERVICE_MANAGER="direct"
    fi
}

print_nginx_info() {
    log "检测到 Nginx"
    log "安装方式: $INSTALL_METHOD"
    log "当前版本: ${NGINX_VERSION:-未知}"
    log "二进制路径: $NGINX_SBIN"
    log "安装前缀: $NGINX_PREFIX"
    log "配置文件: $NGINX_CONF"
    log "PID 文件: $NGINX_PID_PATH"
    log "运行管理方式: $ORIGINAL_SERVICE_MANAGER"
    [ -n "$CONFIGURE_ARGS" ] && log "编译参数: $CONFIGURE_ARGS"
}

fetch_url() {
    local url=$1
    if command -v curl &>/dev/null; then
        curl -fsSL "$url"
    elif command -v wget &>/dev/null; then
        wget -qO- "$url"
    else
        return 1
    fi
}

download_file() {
    local url=$1
    local output=$2
    if command -v curl &>/dev/null; then
        curl -fL --progress-bar -o "$output" "$url"
    elif command -v wget &>/dev/null; then
        if wget --help 2>&1 | grep -q -- '--show-progress'; then
            wget -q --show-progress -O "$output" "$url"
        else
            wget -O "$output" "$url"
        fi
    else
        err "未找到 curl 或 wget，无法在线下载"
        return 1
    fi
}

nginx_source_available() {
    local version=$1
    local url="https://nginx.org/download/nginx-${version}.tar.gz"

    if command -v curl &>/dev/null; then
        curl -fsIL --connect-timeout 10 --max-time 20 "$url" >/dev/null 2>&1
    elif command -v wget &>/dev/null; then
        wget --spider -q -T 20 "$url" >/dev/null 2>&1
    else
        return 1
    fi
}

fetch_nginx_versions() {
    if ! command -v perl &>/dev/null; then
        return 1
    fi

    fetch_url "https://nginx.org/en/download.html" 2>/dev/null | perl -0777 -ne '
      my $ok = 0;

      if (/Mainline version.*?nginx-([0-9]+\.[0-9]+\.[0-9]+)/s) {
        printf "Mainline version(主线版本) : %s\n", $1;
        $ok++;
      }

      if (/Stable version.*?nginx-([0-9]+\.[0-9]+\.[0-9]+)/s) {
        printf "Stable version(稳定版)     : %s\n", $1;
        $ok++;
      }

      if (/Legacy versions(.*)/s) {
        my $legacy = $1;
        my %seen;
        my $i = 0;

        while ($legacy =~ /nginx-([0-9]+\.[0-9]+\.[0-9]+)/g) {
          next if $seen{$1}++;
          printf "Legacy versions(旧版本)    : %s\n", $1;
          last if ++$i >= 5;
        }
      }

      exit($ok >= 2 ? 0 : 1);
    '
}

run_with_spinner() {
    local message=$1
    local output_file=$2
    shift 2
    local spin='-\|/'
    local i=0
    local pid

    "$@" > "$output_file" 2>/dev/null &
    pid=$!

    while kill -0 "$pid" 2>/dev/null; do
        i=$(( (i + 1) % 4 ))
        printf "\r%s %s" "${spin:$i:1}" "$message"
        sleep 0.15
    done

    wait "$pid"
    local status=$?
    printf "\r%-80s\r" " "
    return "$status"
}

read_manual_version() {
    prompt_read TARGET_VERSION "请输入 Nginx 版本号（例如 1.30.1）: "
}

version_in_list() {
    local version=$1
    shift
    local item

    for item in "$@"; do
        [ "$item" = "$version" ] && return 0
    done
    return 1
}

manual_version_available() {
    local version=$1

    if nginx_source_available "$version"; then
        return 0
    fi

    warn "未在 Nginx 官方下载源找到版本 ${version}"
    warn "请重新选择列表版本，或输入 Nginx 官方已发布版本号"
    return 1
}

validate_target_version() {
    if ! echo "$TARGET_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
        err "版本号格式不正确，应为 x.y.z"
        exit 1
    fi
    log "目标版本: $TARGET_VERSION"
}

select_install_version() {
    title "选择 Nginx 版本"

    local output=""
    local output_file=""
    local versions=()
    local labels=()
    local choice=""

    if ! command -v perl &>/dev/null; then
        warn "当前系统缺少 perl，无法解析 Nginx 官方版本页面，请手动输入版本号"
    else
        output_file=$(mktemp /tmp/nginx_versions_XXXXXX)
        if run_with_spinner "正在在线获取 Nginx 官方版本..." "$output_file" fetch_nginx_versions; then
            output=$(cat "$output_file")
        fi
        rm -f "$output_file"
    fi

    if [ -n "$output" ]; then
        echo "$output"
        while IFS= read -r line; do
            local version
            version=$(echo "$line" | awk -F': ' '{print $2}' | tr -d ' ')
            if echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
                labels+=("$line")
                versions+=("$version")
            fi
        done <<< "$output"
    fi

    if [ ${#versions[@]} -gt 0 ]; then
        echo ""
        echo "  请选择要安装的版本:"
        for i in "${!versions[@]}"; do
            printf "  [%d] %s\n" $((i+1)) "${labels[$i]}"
        done
        echo "  [m] 手动输入版本"
        echo ""
        while true; do
            prompt_read choice "请选择版本 [1-${#versions[@]}/m，或直接输入版本号]: "

            if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#versions[@]}" ]; then
                TARGET_VERSION="${versions[$((choice-1))]}"
                break
            elif [[ "$choice" =~ ^[Mm]$ ]]; then
                read_manual_version
                if ! echo "$TARGET_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
                    warn "版本号格式不正确，应为 x.y.z"
                elif version_in_list "$TARGET_VERSION" "${versions[@]}" || manual_version_available "$TARGET_VERSION"; then
                    break
                fi
            elif [[ "$choice" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
                TARGET_VERSION="$choice"
                if version_in_list "$TARGET_VERSION" "${versions[@]}" || manual_version_available "$TARGET_VERSION"; then
                    break
                fi
            else
                warn "无效选择，请输入 1-${#versions[@]}、m，或版本号（例如 1.30.1）"
            fi
        done
    else
        warn "获取 Nginx 官方版本失败，请检查网络或手动输入版本号。"
        read_manual_version
    fi

    validate_target_version
}

ask_install_options() {
    title "安装参数"

    local install_prefix=""
    echo "默认安装目录: $DEFAULT_INSTALL_PREFIX"
    prompt_read install_prefix "请输入安装目录（直接回车使用默认值）: "
    install_prefix=${install_prefix:-$DEFAULT_INSTALL_PREFIX}

    CONFIGURE_ARGS="--prefix=${install_prefix} ${CONFIGURE_MODULES}"
    NGINX_PREFIX="$install_prefix"
    NGINX_SBIN="${NGINX_PREFIX}/sbin/nginx"
    NGINX_CONF="${NGINX_PREFIX}/conf/nginx.conf"
    NGINX_PID_PATH="${NGINX_PREFIX}/logs/nginx.pid"

    echo ""
    echo "默认编译参数:"
    echo "  $CONFIGURE_ARGS"
    echo ""
    prompt_read OFFLINE_PACKAGE "请输入离线源码包完整路径（留空则在线下载）: "

    if [ -d "$NGINX_PREFIX" ] && [ "$(ls -A "$NGINX_PREFIX" 2>/dev/null)" ]; then
        warn "安装目录已存在且不为空: $NGINX_PREFIX"
        prompt_read confirm_prefix "继续安装可能覆盖目录内文件，确认继续？[y/N]: "
        if [[ ! "$confirm_prefix" =~ ^[Yy]$ ]]; then
            log "用户取消安装"
            exit 0
        fi
    fi
}

check_source_install_deps() {
    title "检查编译依赖"

    local missing=()
    local required_cmds=(gcc g++ autoconf automake make tar grep sed awk)

    for cmd in "${required_cmds[@]}"; do
        command -v "$cmd" &>/dev/null || missing+=("$cmd")
    done

    if [ ${#missing[@]} -gt 0 ]; then
        warn "缺少依赖: ${missing[*]}，正在尝试安装..."
        if command -v dnf &>/dev/null; then
            dnf install -y pcre-devel zlib-devel openssl-devel gcc gcc-c++ autoconf automake make tar >> "$LOG_FILE" 2>&1
        elif command -v yum &>/dev/null; then
            yum install -y pcre-devel zlib-devel openssl-devel gcc gcc-c++ autoconf automake make tar >> "$LOG_FILE" 2>&1
        elif command -v apt-get &>/dev/null; then
            apt-get update >> "$LOG_FILE" 2>&1
            apt-get install -y build-essential autoconf automake libpcre3-dev zlib1g-dev libssl-dev >> "$LOG_FILE" 2>&1
        elif command -v apk &>/dev/null; then
            apk add gcc g++ autoconf automake make tar pcre-dev zlib-dev openssl-dev linux-headers >> "$LOG_FILE" 2>&1
        elif command -v zypper &>/dev/null; then
            zypper install -y pcre-devel zlib-devel libopenssl-devel gcc gcc-c++ autoconf automake make tar >> "$LOG_FILE" 2>&1
        else
            err "无法自动安装依赖，请手动安装: ${missing[*]}"
            exit 1
        fi
    fi

    log "编译依赖检查通过"
}

create_nginx_user() {
    title "创建运行用户"

    if ! getent group nginx &>/dev/null; then
        groupadd -r nginx
        log "已创建 nginx 用户组"
    else
        log "nginx 用户组已存在"
    fi

    if ! id nginx &>/dev/null; then
        if useradd -r -g nginx -s /sbin/nologin -M nginx 2>/dev/null; then
            log "已创建 nginx 用户"
        else
            useradd -r -g nginx -s /bin/false -M nginx
            log "已创建 nginx 用户"
        fi
    else
        log "nginx 用户已存在"
    fi
}

prepare_nginx_source() {
    title "准备源码包"

    BUILD_DIR=$(mktemp -d /tmp/nginx_manage_build_XXXXXX)
    local package_file="$BUILD_DIR/nginx-${TARGET_VERSION}.tar.gz"

    if [ -n "$OFFLINE_PACKAGE" ]; then
        log "使用离线源码包: $OFFLINE_PACKAGE"
        if [ ! -f "$OFFLINE_PACKAGE" ]; then
            err "离线源码包不存在: $OFFLINE_PACKAGE"
            exit 1
        fi
        cp -f "$OFFLINE_PACKAGE" "$package_file"
    else
        local url="https://nginx.org/download/nginx-${TARGET_VERSION}.tar.gz"
        log "下载源码: $url"
        download_file "$url" "$package_file" 2>&1 | tee -a "$LOG_FILE"
    fi

    local filesize
    filesize=$(stat -c%s "$package_file" 2>/dev/null || stat -f%z "$package_file")
    if [ -z "$filesize" ] || [ "$filesize" -lt 1024 ]; then
        err "源码包异常，请检查版本号、网络或离线包路径"
        exit 1
    fi

    tar -zxf "$package_file" -C "$BUILD_DIR"
    if [ ! -d "$BUILD_DIR/nginx-${TARGET_VERSION}" ]; then
        err "源码包解压后未找到目录: nginx-${TARGET_VERSION}"
        exit 1
    fi
    log "源码准备完成"
}

compile_and_install_source() {
    title "编译安装 Nginx"

    cd "$BUILD_DIR/nginx-${TARGET_VERSION}"
    log "执行 configure..."
    if ! eval "./configure $CONFIGURE_ARGS" >> "$LOG_FILE" 2>&1; then
        err "configure 失败，详见: $LOG_FILE"
        exit 1
    fi

    local cores
    cores=$(nproc 2>/dev/null || echo 2)
    log "开始编译（${cores} 核心并行）..."
    if ! make -j"$cores" >> "$LOG_FILE" 2>&1; then
        err "编译失败，详见: $LOG_FILE"
        exit 1
    fi

    log "执行 make install..."
    if ! make install >> "$LOG_FILE" 2>&1; then
        err "安装失败，详见: $LOG_FILE"
        exit 1
    fi

    local installed_ver
    installed_ver=$("$NGINX_SBIN" -v 2>&1 | sed -n 's|.*nginx/\([0-9.]*\).*|\1|p')
    if [ "$installed_ver" != "$TARGET_VERSION" ]; then
        err "安装后版本不匹配，期望 $TARGET_VERSION，实际 ${installed_ver:-未知}"
        exit 1
    fi
    log "Nginx 安装成功: $installed_ver"
}

compile_source_binary() {
    title "编译 Nginx"

    cd "$BUILD_DIR/nginx-${TARGET_VERSION}"
    log "执行 configure..."
    if ! eval "./configure $CONFIGURE_ARGS" >> "$LOG_FILE" 2>&1; then
        err "configure 失败，详见: $LOG_FILE"
        exit 1
    fi

    local cores
    cores=$(nproc 2>/dev/null || echo 2)
    log "开始编译（${cores} 核心并行）..."
    if ! make -j"$cores" >> "$LOG_FILE" 2>&1; then
        err "编译失败，详见: $LOG_FILE"
        exit 1
    fi

    if [ ! -f "$BUILD_DIR/nginx-${TARGET_VERSION}/objs/nginx" ]; then
        err "编译产物不存在: objs/nginx"
        exit 1
    fi

    local compiled_ver
    compiled_ver=$("$BUILD_DIR/nginx-${TARGET_VERSION}/objs/nginx" -v 2>&1 | sed -n 's|.*nginx/\([0-9.]*\).*|\1|p')
    if [ "$compiled_ver" != "$TARGET_VERSION" ]; then
        err "编译后版本不匹配，期望 $TARGET_VERSION，实际 ${compiled_ver:-未知}"
        exit 1
    fi

    log "编译成功: $compiled_ver"
}

test_new_binary_with_current_config() {
    title "测试现有配置兼容性"

    local new_binary="$BUILD_DIR/nginx-${TARGET_VERSION}/objs/nginx"
    if "$new_binary" -t -c "$NGINX_CONF" 2>&1 | tee -a "$LOG_FILE"; then
        log "新二进制配置测试通过"
    else
        err "现有配置与新版本不兼容，已停止升级"
        exit 1
    fi
}

create_nginx_symlinks() {
    title "创建软链接"

    mkdir -p /usr/local/sbin
    if [ -d "${NGINX_PREFIX}/sbin" ]; then
        ln -sf "${NGINX_PREFIX}/sbin/"* /usr/local/sbin/
        log "已创建软链接到 /usr/local/sbin/"
    else
        warn "未找到 sbin 目录，跳过软链接创建: ${NGINX_PREFIX}/sbin"
    fi
}

test_nginx_config() {
    title "测试 Nginx 配置"

    if "$NGINX_SBIN" -t -c "$NGINX_CONF" 2>&1 | tee -a "$LOG_FILE"; then
        log "Nginx 配置测试通过"
    else
        err "Nginx 配置测试失败"
        exit 1
    fi
}

setup_nginx_systemd() {
    title "配置 systemd 服务"

    if ! command -v systemctl &>/dev/null; then
        warn "当前系统未检测到 systemctl，跳过 systemd 服务配置"
        return
    fi

    echo "请选择启动管理方式:"
    echo "  Y = 创建 nginx.service，并使用 systemctl 管理启动/停止/重启/开机自启"
    echo "  n = 不创建 systemd 服务，安装后使用 nginx 二进制直接启动"
    echo ""
    prompt_read service_choice "是否创建并启动 nginx systemd 服务？[Y/n]: "
    if [[ "$service_choice" =~ ^[Nn]$ ]]; then
        log "跳过 systemd 服务配置"
        if "$NGINX_SBIN" -c "$NGINX_CONF" >> "$LOG_FILE" 2>&1; then
            SERVICE_MANAGER="direct"
            log "Nginx 已直接启动: $NGINX_SBIN"
        else
            err "Nginx 直接启动失败，详见: $LOG_FILE"
            exit 1
        fi
        return
    fi

    cat > /etc/systemd/system/nginx.service << EOF
[Unit]
Description=Nginx HTTP Server
After=network.target

[Service]
Type=forking
ExecStart=${NGINX_SBIN} -c ${NGINX_CONF}
ExecReload=${NGINX_SBIN} -s reload
ExecStop=${NGINX_SBIN} -s quit
PIDFile=${NGINX_PID_PATH}
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable nginx >> "$LOG_FILE" 2>&1
    if "$NGINX_SBIN" -t -c "$NGINX_CONF" >> "$LOG_FILE" 2>&1; then
        systemctl restart nginx
        SERVICE_MANAGER="systemd"
        log "nginx systemd 服务已启动并设置开机自启"
    else
        err "配置检测失败，服务未启动，详见: $LOG_FILE"
        exit 1
    fi
}

print_install_commands() {
    title "管理命令"

    if [ "$SERVICE_MANAGER" = "systemd" ]; then
        log "启动: systemctl start nginx"
        log "停止: systemctl stop nginx"
        log "重启: systemctl restart nginx"
        log "重载: systemctl reload nginx"
        log "状态: systemctl status nginx"
    else
        log "已创建软链接，可直接使用 nginx 命令管理"
        log "启动: nginx"
        log "停止: nginx -s quit"
        log "重启: nginx -s quit && nginx"
        log "重载: nginx -s reload"
        log "状态: ps -ef | grep '[n]ginx'"
        warn "当前未创建 systemd 服务，开机自启动需要后续手动配置"
    fi

    log "测试配置: nginx -t"
}

nginx_config_status() {
    if [ -n "${NGINX_SBIN:-}" ] && [ -x "$NGINX_SBIN" ] && [ -n "${NGINX_CONF:-}" ] && [ -f "$NGINX_CONF" ]; then
        if "$NGINX_SBIN" -t -c "$NGINX_CONF" >> "$LOG_FILE" 2>&1; then
            echo "通过"
        else
            echo "失败"
        fi
    else
        echo "未检测"
    fi
}

nginx_runtime_status() {
    if [ "${SERVICE_MANAGER:-${ORIGINAL_SERVICE_MANAGER:-}}" = "systemd" ] && command -v systemctl &>/dev/null; then
        local active
        active=$(systemctl is-active nginx 2>/dev/null || true)
        if [ "$active" = "active" ]; then
            echo "systemd active"
            return
        fi
    fi

    if [ -n "${NGINX_PID_PATH:-}" ] && [ -f "$NGINX_PID_PATH" ]; then
        local pid
        pid=$(cat "$NGINX_PID_PATH" 2>/dev/null || true)
        if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
            echo "运行中 (PID: $pid)"
            return
        fi
    fi

    if pgrep -x nginx &>/dev/null; then
        echo "运行中 (pgrep)"
    else
        echo "未运行"
    fi
}

log_nginx_operation_summary() {
    log "安装方式: ${INSTALL_METHOD:-source}"
    log "安装前缀: ${NGINX_PREFIX:-未检测}"
    log "二进制路径: ${NGINX_SBIN:-未检测}"
    log "配置文件: ${NGINX_CONF:-未检测}"
    log "PID 文件: ${NGINX_PID_PATH:-未检测}"
    log "运行管理方式: ${SERVICE_MANAGER:-${ORIGINAL_SERVICE_MANAGER:-未检测}}"
    log "配置测试: $(nginx_config_status)"
    log "运行状态: $(nginx_runtime_status)"
    [ -n "${BACKUP_DIR:-}" ] && log "备份位置: $BACKUP_DIR"
    log "操作日志: $LOG_FILE"
}

post_operation_menu() {
    local action=""

    echo ""
    echo "操作完成："
    echo "  [1] 返回主菜单"
    echo "  [0] 退出脚本"
    echo ""

    while true; do
        prompt_read action "请输入选择 [1/0]: "
        case "$action" in
            1) return 0 ;;
            0) log "操作日志: $LOG_FILE"; log "已退出"; exit 0 ;;
            *) warn "无效选择" ;;
        esac
    done
}

backup_before_upgrade() {
    BACKUP_DIR="${NGINX_PREFIX}/backup_$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$BACKUP_DIR"
    log "正在备份到: $BACKUP_DIR"

    cp -f "$NGINX_SBIN" "$BACKUP_DIR/nginx.old"

    if [ -n "$NGINX_CONF" ] && [ -f "$NGINX_CONF" ]; then
        local conf_dir
        conf_dir=$(dirname "$NGINX_CONF")
        cp -a "$conf_dir" "$BACKUP_DIR/conf"
    fi

    {
        echo "version=${NGINX_VERSION:-}"
        echo "target=${TARGET_VERSION:-}"
        echo "trigger=覆盖安装 ${TARGET_VERSION:-未知} 前"
        echo "method=${INSTALL_METHOD:-}"
        echo "sbin=${NGINX_SBIN:-}"
        echo "prefix=${NGINX_PREFIX:-}"
        echo "conf=${NGINX_CONF:-}"
        echo "pid=${NGINX_PID_PATH:-}"
        echo "configure=${CONFIGURE_ARGS:-}"
    } > "$BACKUP_DIR/meta.txt"

    log "备份完成"
}

backup_before_rollback() {
    BACKUP_DIR="${NGINX_PREFIX}/backup_$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$BACKUP_DIR"
    log "正在备份回滚前当前版本到: $BACKUP_DIR"

    cp -f "$NGINX_SBIN" "$BACKUP_DIR/nginx.old"

    if [ -n "$NGINX_CONF" ] && [ -f "$NGINX_CONF" ]; then
        local conf_dir
        conf_dir=$(dirname "$NGINX_CONF")
        cp -a "$conf_dir" "$BACKUP_DIR/conf"
    fi

    {
        echo "version=${NGINX_VERSION:-}"
        echo "target="
        echo "trigger=回滚前自动备份"
        echo "method=${INSTALL_METHOD:-}"
        echo "sbin=${NGINX_SBIN:-}"
        echo "prefix=${NGINX_PREFIX:-}"
        echo "conf=${NGINX_CONF:-}"
        echo "pid=${NGINX_PID_PATH:-}"
        echo "configure=${CONFIGURE_ARGS:-}"
    } > "$BACKUP_DIR/meta.txt"

    log "回滚前备份完成"
}

restart_after_binary_replace() {
    title "重启 Nginx"

    if [ "$ORIGINAL_SERVICE_MANAGER" = "systemd" ]; then
        SERVICE_MANAGER="systemd"
        systemctl restart nginx
        log "已通过 systemd 重启 Nginx"
        return
    fi

    SERVICE_MANAGER="direct"
    if [ -f "$NGINX_PID_PATH" ]; then
        local pid
        pid=$(cat "$NGINX_PID_PATH" 2>/dev/null || true)
        if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
            kill -QUIT "$pid" 2>/dev/null || true
            local i=0
            while kill -0 "$pid" 2>/dev/null && [ $i -lt 15 ]; do
                sleep 1
                i=$((i+1))
            done
        fi
    fi

    "$NGINX_SBIN" -c "$NGINX_CONF"
    log "已通过 nginx 二进制直接启动"
}

rollback_replaced_binary() {
    if [ -n "$BACKUP_DIR" ] && [ -f "$BACKUP_DIR/nginx.old" ] && [ -n "$NGINX_SBIN" ]; then
        cp -f "$BACKUP_DIR/nginx.old" "$NGINX_SBIN"
        warn "已恢复旧二进制: $NGINX_SBIN"
    fi
}

replace_binary_and_restart() {
    title "替换二进制"

    local new_binary="$BUILD_DIR/nginx-${TARGET_VERSION}/objs/nginx"
    cp -f "$new_binary" "$NGINX_SBIN"
    log "已替换二进制: $NGINX_SBIN"

    if ! "$NGINX_SBIN" -t -c "$NGINX_CONF" >> "$LOG_FILE" 2>&1; then
        err "替换后配置测试失败，正在恢复旧二进制"
        rollback_replaced_binary
        exit 1
    fi

    if ! restart_after_binary_replace; then
        err "重启失败，正在恢复旧二进制"
        rollback_replaced_binary
        restart_after_binary_replace || true
        exit 1
    fi
}

install_nginx() {
    if [ "$NGINX_FOUND" = true ]; then
        warn "已检测到 Nginx，请使用升级/覆盖安装指定版本"
        return
    fi

    select_install_version
    ask_install_options
    check_source_install_deps
    create_nginx_user
    prepare_nginx_source
    compile_and_install_source
    create_nginx_symlinks
    test_nginx_config
    setup_nginx_systemd
    print_install_commands

    title "安装结果"
    log "安装方式: source"
    log "版本: $TARGET_VERSION"
    log "安装目录: $NGINX_PREFIX"
    log "二进制路径: $NGINX_SBIN"
    log "配置文件: $NGINX_CONF"
    log_nginx_operation_summary
    post_operation_menu
}

upgrade_nginx() {
    if [ "$NGINX_FOUND" != true ]; then
        warn "未检测到 Nginx，请使用安装指定版本"
        return
    fi

    if [ "$INSTALL_METHOD" != "source" ]; then
        warn "当前管理脚本的升级/覆盖安装暂仅支持源码编译安装的 Nginx"
        warn "检测到当前安装方式为: $INSTALL_METHOD"
        return
    fi

    select_install_version

    if [ "$TARGET_VERSION" = "$NGINX_VERSION" ]; then
        warn "目标版本与当前版本相同，无需升级"
        return
    fi

    echo ""
    log "将复用当前 Nginx 编译参数:"
    echo "  $CONFIGURE_ARGS"
    echo ""
    prompt_read OFFLINE_PACKAGE "请输入离线源码包完整路径（留空则在线下载）: "

    title "即将执行升级/覆盖安装"
    echo "  当前版本: ${NGINX_VERSION:-未知}"
    echo "  目标版本: $TARGET_VERSION"
    echo "  二进制路径: $NGINX_SBIN"
    echo "  配置文件: $NGINX_CONF"
    echo "  编译参数: $CONFIGURE_ARGS"
    [ -n "$OFFLINE_PACKAGE" ] && echo "  离线源码包: $OFFLINE_PACKAGE"
    echo ""
    prompt_read confirm_upgrade "确认继续升级？[Y/n]: "
    if [[ "$confirm_upgrade" =~ ^[Nn]$ ]]; then
        log "用户取消升级"
        return
    fi

    check_source_install_deps
    create_nginx_user
    prepare_nginx_source
    compile_source_binary
    test_new_binary_with_current_config
    backup_before_upgrade
    replace_binary_and_restart
    create_nginx_symlinks
    print_install_commands

    local final_ver
    final_ver=$("$NGINX_SBIN" -v 2>&1 | sed -n 's|.*nginx/\([0-9.]*\).*|\1|p')

    title "升级结果"
    log "安装方式: source"
    log "原版本: ${NGINX_VERSION:-未知}"
    log "目标版本: $TARGET_VERSION"
    log "当前版本: ${final_ver:-未知}"
    if [ "$final_ver" = "$TARGET_VERSION" ]; then
        log "版本验证: 通过"
    else
        err "版本验证: 失败"
    fi
    log_nginx_operation_summary
    log "如需回滚，请先输入 [1] 返回主菜单，再选择 [3] 回滚 Nginx"
    post_operation_menu
}

confirm_uninstall() {
    echo ""
    echo -e "${YELLOW}即将卸载当前 Nginx:${NC}"
    echo "  安装方式: $INSTALL_METHOD"
    echo "  当前版本: ${NGINX_VERSION:-未知}"
    echo "  二进制路径: $NGINX_SBIN"
    echo "  安装前缀: $NGINX_PREFIX"
    echo "  配置文件: $NGINX_CONF"
    echo ""
    echo -e "${YELLOW}默认会先备份配置和二进制文件。源码安装默认只删除二进制和软链接，不删除配置/站点目录。${NC}"
    echo ""
    prompt_read confirm "确认卸载请输入 uninstall: "
    if [ "$confirm" != "uninstall" ]; then
        log "用户取消卸载"
        return 1
    fi
}

backup_before_uninstall() {
    BACKUP_DIR="/opt/nginx_manage_backup/uninstall_$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$BACKUP_DIR"
    log "正在备份到: $BACKUP_DIR"

    [ -n "$NGINX_SBIN" ] && [ -f "$NGINX_SBIN" ] && cp -f "$NGINX_SBIN" "$BACKUP_DIR/nginx.bin"

    if [ -n "$NGINX_CONF" ] && [ -f "$NGINX_CONF" ]; then
        local conf_dir
        conf_dir=$(dirname "$NGINX_CONF")
        cp -a "$conf_dir" "$BACKUP_DIR/conf"
    fi

    if [ -n "$NGINX_PREFIX" ] && [ -d "$NGINX_PREFIX/html" ]; then
        cp -a "$NGINX_PREFIX/html" "$BACKUP_DIR/html"
    fi

    {
        echo "version=${NGINX_VERSION:-}"
        echo "method=${INSTALL_METHOD:-}"
        echo "sbin=${NGINX_SBIN:-}"
        echo "prefix=${NGINX_PREFIX:-}"
        echo "conf=${NGINX_CONF:-}"
        echo "pid=${NGINX_PID_PATH:-}"
    } > "$BACKUP_DIR/meta.txt"

    log "备份完成"
}

stop_nginx_for_uninstall() {
    title "停止 Nginx"

    if command -v systemctl &>/dev/null && systemctl list-unit-files nginx.service &>/dev/null 2>&1; then
        systemctl stop nginx 2>/dev/null || true
        systemctl disable nginx 2>/dev/null || true
        log "已尝试停止并禁用 systemd nginx 服务"
    fi

    if command -v service &>/dev/null; then
        service nginx stop 2>/dev/null || true
    fi

    if [ -n "$NGINX_PID_PATH" ] && [ -f "$NGINX_PID_PATH" ]; then
        local pid
        pid=$(cat "$NGINX_PID_PATH" 2>/dev/null || true)
        if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
            kill -QUIT "$pid" 2>/dev/null || true
            local i=0
            while kill -0 "$pid" 2>/dev/null && [ $i -lt 15 ]; do
                sleep 1
                i=$((i+1))
            done
        fi
    elif [ -n "$NGINX_SBIN" ] && [ -x "$NGINX_SBIN" ]; then
        "$NGINX_SBIN" -s quit 2>/dev/null || true
    fi

    if pgrep -x nginx &>/dev/null; then
        warn "仍检测到 nginx 进程，请卸载后手动确认是否需要处理"
    else
        log "Nginx 已停止"
    fi
}

remove_nginx_symlinks() {
    title "清理软链接"

    local dirs=(/usr/local/sbin /usr/sbin /usr/bin /usr/local/bin)
    local link target
    for dir in "${dirs[@]}"; do
        [ -d "$dir" ] || continue
        for link in "$dir"/nginx; do
            [ -L "$link" ] || continue
            target=$(readlink -f "$link" 2>/dev/null || true)
            if [ "$target" = "$NGINX_SBIN" ]; then
                rm -f "$link"
                log "已删除软链接: $link"
            fi
        done
    done
}

remove_source_nginx() {
    title "卸载源码安装的 Nginx"

    remove_nginx_symlinks

    if [ -n "$NGINX_SBIN" ] && [ -f "$NGINX_SBIN" ]; then
        rm -f "$NGINX_SBIN"
        log "已删除二进制文件: $NGINX_SBIN"
    fi

    if command -v systemctl &>/dev/null && [ -f /etc/systemd/system/nginx.service ]; then
        if grep -q "$NGINX_PREFIX\|$NGINX_SBIN" /etc/systemd/system/nginx.service 2>/dev/null; then
            rm -f /etc/systemd/system/nginx.service
            systemctl daemon-reload 2>/dev/null || true
            log "已删除源码安装的 systemd 服务文件"
        else
            warn "检测到 /etc/systemd/system/nginx.service，但内容未匹配当前安装路径，已保留"
        fi
    fi

    if [ -d "$NGINX_PREFIX" ]; then
        echo ""
        prompt_read delete_prefix "是否删除安装前缀目录 $NGINX_PREFIX（会删除配置/站点文件）？[y/N]: "
        if [[ "$delete_prefix" =~ ^[Yy]$ ]]; then
            prompt_read delete_confirm "高危确认：请输入 delete-prefix 继续删除 $NGINX_PREFIX: "
            if [ "$delete_confirm" = "delete-prefix" ]; then
                rm -rf "$NGINX_PREFIX"
                log "已删除安装前缀目录: $NGINX_PREFIX"
            else
                warn "确认词不匹配，已保留安装前缀目录"
            fi
        else
            log "已保留安装前缀目录: $NGINX_PREFIX"
        fi
    fi
}

remove_package_nginx() {
    title "通过包管理器卸载 Nginx"

    case "$INSTALL_METHOD" in
        yum)
            yum remove -y nginx 2>&1 | tee -a "$LOG_FILE"
            ;;
        dnf)
            dnf remove -y nginx 2>&1 | tee -a "$LOG_FILE"
            ;;
        apt)
            apt-get remove -y nginx nginx-common nginx-core 2>&1 | tee -a "$LOG_FILE"
            ;;
        apk)
            apk del nginx 2>&1 | tee -a "$LOG_FILE"
            ;;
        zypper)
            zypper remove -y nginx 2>&1 | tee -a "$LOG_FILE"
            ;;
        *)
            err "不支持的包管理器卸载方式: $INSTALL_METHOD"
            return 1
            ;;
    esac

    warn "包管理器卸载默认保留配置文件；如需彻底清理，请手动确认后删除相关配置目录"
}

uninstall_nginx() {
    if [ "$NGINX_FOUND" != true ]; then
        warn "未检测到 Nginx，无法执行卸载"
        return
    fi

    if ! confirm_uninstall; then
        return 0
    fi
    backup_before_uninstall
    stop_nginx_for_uninstall

    case "$INSTALL_METHOD" in
        source)
            remove_source_nginx
            ;;
        yum|dnf|apt|apk|zypper)
            remove_package_nginx
            ;;
        *)
            err "未知安装方式，已停止服务并完成备份，但未删除文件: $INSTALL_METHOD"
            return 1
            ;;
    esac

    title "卸载结果"
    log "安装方式: ${INSTALL_METHOD:-未知}"
    log "安装前缀: ${NGINX_PREFIX:-未检测}"
    log "二进制路径: ${NGINX_SBIN:-未检测}"
    log "配置文件: ${NGINX_CONF:-未检测}"
    if [ -n "$NGINX_SBIN" ] && [ -e "$NGINX_SBIN" ]; then
        warn "二进制文件仍存在: $NGINX_SBIN"
    else
        log "二进制文件已移除"
    fi
    log "运行状态: $(nginx_runtime_status)"
    log "备份位置: $BACKUP_DIR"
    log "卸载日志: $LOG_FILE"
    post_operation_menu
}

load_upgrade_backups() {
    BACKUPS=()

    if [ -n "$NGINX_PREFIX" ] && [ -d "$NGINX_PREFIX" ]; then
        while IFS= read -r dir; do
            [ -f "$dir/nginx.old" ] && BACKUPS+=("$dir")
        done < <(find "$NGINX_PREFIX" -maxdepth 1 -type d -name "backup_*" 2>/dev/null | sort -r)
    fi
}

backup_time_label() {
    local backup_dir=$1
    local backup_name
    backup_name=$(basename "$backup_dir" | sed 's/^backup_//')
    echo "$backup_name" | sed 's/\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)_\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1-\2-\3 \4:\5:\6/'
}

read_backup_meta() {
    local meta_file=$1
    local key=$2

    [ -f "$meta_file" ] || return 0
    awk -F= -v key="$key" '$1 == key { sub(/^[^=]*=/, ""); print; exit }' "$meta_file" 2>/dev/null || true
}

print_backup_list() {
    local i

    for i in "${!BACKUPS[@]}"; do
        local bdir="${BACKUPS[$i]}"
        local old_ver="未知"
        local target_ver=""
        local trigger=""
        local method="未知"
        local size="-"

        if [ -f "$bdir/meta.txt" ]; then
            old_ver=$(read_backup_meta "$bdir/meta.txt" "version")
            target_ver=$(read_backup_meta "$bdir/meta.txt" "target")
            trigger=$(read_backup_meta "$bdir/meta.txt" "trigger")
            method=$(read_backup_meta "$bdir/meta.txt" "method")
        fi
        old_ver=${old_ver:-未知}
        method=${method:-未知}
        if [ -z "$trigger" ] && [ -n "$target_ver" ]; then
            trigger="覆盖安装 ${target_ver} 前"
        elif [ -z "$trigger" ]; then
            trigger="未知"
        fi
        size=$(du -sh "$bdir" 2>/dev/null | awk '{print $1}' || true)
        size=${size:-"-"}

        printf "  [%d] 备份版本: %s | 触发操作: %s | 方式: %s | 时间: %s | 大小: %s | 路径: %s\n" \
            $((i+1)) "$old_ver" "$trigger" "$method" "$(backup_time_label "$bdir")" "$size" "$bdir"
    done
}

rollback_nginx() {
    if [ "$NGINX_FOUND" != true ]; then
        warn "未检测到 Nginx，无法执行回滚"
        return
    fi

    load_upgrade_backups

    if [ ${#BACKUPS[@]} -eq 0 ]; then
        warn "未找到可用升级备份"
        warn "备份通常位于: ${NGINX_PREFIX}/backup_*"
        return
    fi

    title "可回滚备份"
    print_backup_list

    echo ""
    prompt_read choice "请选择要回滚到的备份编号 [1-${#BACKUPS[@]}，0取消]: "
    if [ "$choice" = "0" ]; then
        log "用户取消回滚"
        return
    fi
    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt ${#BACKUPS[@]} ]; then
        warn "无效选择，已取消回滚"
        return
    fi

    local selected="${BACKUPS[$((choice-1))]}"
    if [ ! -f "$selected/nginx.old" ]; then
        err "备份不完整，缺少 nginx.old: $selected"
        return 1
    fi

    echo ""
    prompt_read confirm "确认回滚到该备份？[Y/n]: "
    if [[ "$confirm" =~ ^[Nn]$ ]]; then
        log "用户取消回滚"
        return
    fi

    prompt_read backup_current "回滚前是否备份当前版本？[Y/n]: "
    if [[ ! "$backup_current" =~ ^[Nn]$ ]]; then
        backup_before_rollback
    else
        warn "已跳过回滚前当前版本备份"
    fi

    title "执行回滚"
    cp -f "$selected/nginx.old" "$NGINX_SBIN"
    log "已恢复二进制: $NGINX_SBIN"

    if [ -d "$selected/conf" ]; then
        prompt_read restore_conf "是否同时恢复配置目录？[y/N]: "
        if [[ "$restore_conf" =~ ^[Yy]$ ]]; then
            local conf_dir
            conf_dir=$(dirname "$NGINX_CONF")
            cp -a "$selected/conf/"* "$conf_dir/"
            log "已恢复配置目录: $conf_dir"
        else
            log "已保留当前配置目录"
        fi
    fi

    if ! "$NGINX_SBIN" -t -c "$NGINX_CONF" >> "$LOG_FILE" 2>&1; then
        err "回滚后配置测试失败，请检查: $LOG_FILE"
        return 1
    fi

    restart_after_binary_replace

    local rolled_ver
    rolled_ver=$("$NGINX_SBIN" -v 2>&1 | sed -n 's|.*nginx/\([0-9.]*\).*|\1|p')
    title "回滚结果"
    log "当前版本: ${rolled_ver:-未知}"
    log "使用备份: $selected"
    log_nginx_operation_summary
    post_operation_menu
}

show_status() {
    if [ "$NGINX_FOUND" = true ]; then
        print_nginx_info
        if [ -f "$NGINX_PID_PATH" ] && kill -0 "$(cat "$NGINX_PID_PATH")" 2>/dev/null; then
            log "运行状态: 运行中 (PID: $(cat "$NGINX_PID_PATH"))"
        else
            warn "运行状态: 未运行或 PID 文件不存在"
        fi
    else
        warn "未检测到 Nginx"
    fi
}

view_backups() {
    if [ "$NGINX_FOUND" != true ]; then
        warn "未检测到 Nginx，无法查看备份"
        return
    fi

    load_upgrade_backups

    if [ ${#BACKUPS[@]} -eq 0 ]; then
        log "未找到升级备份"
        return
    fi

    title "当前升级备份"
    print_backup_list
    log "查看完成，返回主菜单"
}

clean_backups() {
    if [ "$NGINX_FOUND" != true ]; then
        warn "未检测到 Nginx，无法清理备份"
        return
    fi

    load_upgrade_backups

    if [ ${#BACKUPS[@]} -eq 0 ]; then
        log "未找到可清理的升级备份"
        return
    fi

    title "当前升级备份"
    print_backup_list

    echo ""
    if [ ${#BACKUPS[@]} -gt 1 ]; then
        echo "  a = 只保留最新一个备份，删除其余备份"
    fi
    echo "  编号 = 删除指定备份，多个编号用空格分隔，例如: 2 3"
    echo "  q = 取消"
    echo ""
    prompt_read clean_choice "请输入选择: "

    if [ "$clean_choice" = "q" ] || [ -z "$clean_choice" ]; then
        log "用户取消清理"
        return
    fi

    if [ "$clean_choice" = "a" ]; then
        if [ ${#BACKUPS[@]} -le 1 ]; then
            warn "当前只有一个备份，不能执行“只保留最新”清理"
            return
        fi
        prompt_read confirm_keep_latest "确认只保留最新备份并删除其余备份？[y/N]: "
        if [[ ! "$confirm_keep_latest" =~ ^[Yy]$ ]]; then
            log "用户取消清理"
            return
        fi
        for i in "${!BACKUPS[@]}"; do
            [ "$i" -eq 0 ] && continue
            rm -rf "${BACKUPS[$i]}"
            log "已删除备份: ${BACKUPS[$i]}"
        done
        log "清理完成，已保留最新备份: ${BACKUPS[0]}"
        return
    fi

    local selected_indices=()
    local invalid_indices=()
    local idx
    for idx in $clean_choice; do
        if [[ "$idx" =~ ^[0-9]+$ ]] && [ "$idx" -ge 1 ] && [ "$idx" -le ${#BACKUPS[@]} ]; then
            local exists=false
            local selected
            for selected in "${selected_indices[@]}"; do
                if [ "$selected" = "$idx" ]; then
                    exists=true
                    break
                fi
            done
            [ "$exists" = false ] && selected_indices+=("$idx")
        else
            invalid_indices+=("$idx")
        fi
    done

    if [ ${#selected_indices[@]} -eq 0 ]; then
        if [ ${#invalid_indices[@]} -gt 0 ]; then
            warn "无效编号: ${invalid_indices[*]}"
        fi
        warn "未选择有效备份编号，已取消清理"
        return
    fi

    if [ ${#invalid_indices[@]} -gt 0 ]; then
        warn "将跳过无效编号: ${invalid_indices[*]}"
    fi

    prompt_read confirm_delete "确认删除有效备份编号 ${selected_indices[*]}？[y/N]: "
    if [[ ! "$confirm_delete" =~ ^[Yy]$ ]]; then
        log "用户取消清理"
        return
    fi

    for idx in "${selected_indices[@]}"; do
        rm -rf "${BACKUPS[$((idx-1))]}"
        log "已删除备份: ${BACKUPS[$((idx-1))]}"
    done

    log "清理完成"
}

show_menu_when_missing() {
    echo ""
    echo -e "  ${CYAN}[1]${NC} 安装指定版本"
    echo -e "  ${CYAN}[0]${NC} 退出"
    echo ""
    prompt_read action "请输入选择 [1/0]: "

    case "$action" in
        1) install_nginx ;;
        0) log "操作日志: $LOG_FILE"; log "已退出"; exit 0 ;;
        *) warn "无效选择" ;;
    esac
}

show_menu_when_exists() {
    echo ""
    if [ "$INSTALL_METHOD" = "source" ]; then
        echo -e "  ${CYAN}[1]${NC} 升级/覆盖安装指定版本"
    else
        echo -e "  ${CYAN}[1]${NC} 升级/覆盖安装指定版本（仅源码安装支持，当前: ${INSTALL_METHOD}）"
    fi
    echo -e "  ${CYAN}[2]${NC} 卸载 Nginx"
    echo -e "  ${CYAN}[3]${NC} 回滚 Nginx"
    echo -e "  ${CYAN}[4]${NC} 查看状态"
    echo -e "  ${CYAN}[5]${NC} 查看备份"
    echo -e "  ${CYAN}[6]${NC} 清理旧备份"
    echo -e "  ${CYAN}[0]${NC} 退出"
    echo ""
    prompt_read action "请输入选择 [1/2/3/4/5/6/0]: "

    case "$action" in
        1) upgrade_nginx ;;
        2) uninstall_nginx ;;
        3) rollback_nginx ;;
        4) show_status ;;
        5) view_backups ;;
        6) clean_backups ;;
        0) log "操作日志: $LOG_FILE"; log "已退出"; exit 0 ;;
        *) warn "无效选择" ;;
    esac
}

main() {
    cat << 'BANNER'
 _   _       _              _
| \ | | __ _(_)_ __ __  __ | |
|  \| |/ _` | | '_ \\ \/ / | |
| |\  | (_| | | | | |>  <  |_|
|_| \_|\__, |_|_| |_/_/\_\ (_)
        |___/

Nginx Manager
Version : v1.0
Author  : FengYongQi
email   : yongqi0403@163.com
BANNER
    echo ""
    echo "支持: 安装 / 升级 / 卸载 / 回滚"

    check_root

    local first_detect=true
    while true; do
        if [ "$first_detect" = true ]; then
            detect_nginx true
            first_detect=false
        else
            detect_nginx false
        fi

        if [ "$NGINX_FOUND" = true ]; then
            show_menu_when_exists
        else
            show_menu_when_missing
        fi
    done
}

main "$@"
