#!/usr/bin/env bash
# Nexus NX — 统一运维菜单（安装 + 升级 + 日常运维）
#
#   nx                  交互菜单
#   nx update           一键更新（等同 deploy/update.sh）
#   nx update --no-cache  无缓存重建镜像
#   nx install-fresh    全新安装
#   nx health           健康检查
#
set -euo pipefail

NX_SELF="$(readlink -f "${BASH_SOURCE[0]}")"
NX_DIR="$(cd "$(dirname "$NX_SELF")" && pwd)"
# shellcheck source=./nexus-1panel.sh
source "${NX_DIR}/nexus-1panel.sh"

pause_enter() {
    echo ""
    read -r -p "按 Enter 继续..."
}

clear_screen() {
    if [[ -t 1 ]]; then
        clear 2>/dev/null || true
    fi
}

is_stack_installed() {
    [[ -d "${NEXUS_ROOT}/.git" && -f "${NEXUS_ROOT}/${ENV_PROD}" ]]
}

detect_runtime() {
    if is_stack_installed && docker compose version >/dev/null 2>&1; then
        local prof q
        prof="$(profile_env_file "$NEXUS_ROOT")"
        if [[ -f "$prof" && -f "$NEXUS_ROOT/$ENV_PROD" ]]; then
            local -a det_args=(-f "$COMPOSE_FILE")
            if has_1panel_network && [[ -f "$NEXUS_ROOT/$COMPOSE_1PANEL" ]]; then
                det_args+=(-f "$COMPOSE_1PANEL")
            fi
            q="$(cd "$NEXUS_ROOT" && docker compose "${det_args[@]}" \
                --env-file "$ENV_PROD" --env-file "$prof" ps -q nexus 2>/dev/null || true)"
            if [[ -n "$q" ]]; then
                NX_RUNTIME="docker"
                return 0
            fi
        fi
    fi
    if command -v supervisorctl >/dev/null 2>&1 && supervisorctl status nexus >/dev/null 2>&1; then
        NX_RUNTIME="supervisor"
        return 0
    fi
    NX_RUNTIME="none"
}

install_nx_cli() {
    NEXUS_ROOT="$(cd "${NX_DIR}/.." && pwd)" \
        bash "${NX_DIR}/install-nx-cli.sh" 2>/dev/null || true
}

menu_header() {
    local title="$1"
    clear_screen
    echo ""
    echo "╔══════════════════════════════════════════════════════════╗"
    printf "║  Nexus NX — %-44s║\n" "$title"
    echo "╠══════════════════════════════════════════════════════════╣"
    echo "║  域名: ${NEXUS_DOMAIN}   目录: ${NEXUS_ROOT}"
    if is_stack_installed; then
        detect_runtime
        echo "║  运行: ${NX_RUNTIME}   档位: $(cat "${NEXUS_ROOT}/${HOST_PROFILE_FILE}" 2>/dev/null || echo "${NEXUS_PROFILE}")"
        if [[ -d "${NEXUS_ROOT}/.git" ]]; then
            echo "║  版本: $(git -C "${NEXUS_ROOT}" log -1 --oneline 2>/dev/null || echo '?')"
        fi
    else
        echo "║  状态: 未安装"
    fi
    echo "╚══════════════════════════════════════════════════════════╝"
    echo ""
}

run_install() {
    local profile="${1:-2c8g}" extra="${2:-}"
    NEXUS_PROFILE="$profile"
    SKIP_CLONE=false
    FRESH_INSTALL=false
    NO_BACKUP=false
    PRUNE_IMAGES=false
    FROM_ENV="${NEXUS_FROM_ENV}"
    case "$extra" in
        skip-clone) SKIP_CLONE=true ;;
        fresh) FRESH_INSTALL=true ;;
        from-env) FROM_ENV="${NEXUS_FROM_ENV}" ;;
    esac
    load_secrets
    cmd_install
    install_nx_cli
    pause_enter
}

menu_install() {
    while true; do
        menu_header "安装"
        cat <<'EOF'
  [1] 一键安装（默认 2核8G / 2c8g）
  [2] 安装 — 4核16G（4c16g）
  [3] 安装 — 1核4G（1c4g）
  [4] 自定义规格（输入 CPU 与内存 GB）
  [5] 已 clone 到 /opt/nexus，仅 pull + 启动（--skip-clone）
  [6] 全新安装（install-nexus-fresh.sh → /app/install.html）
  [7] 检查端口 / 防火墙（不安装）
  [0] 返回

EOF
        read -r -p "请选择: " choice
        case "$choice" in
            1) run_install 2c8g "" ;;
            2) run_install 4c16g "" ;;
            3) run_install 1c4g "" ;;
            4)
                read -r -p "CPU 核数: " cpus
                read -r -p "内存 GB: " mem
                CUSTOM_CPUS="$cpus"
                CUSTOM_MEM_GB="$mem"
                run_install 2c8g ""
                ;;
            5) run_install 2c8g skip-clone ;;
            6)
                if [[ -x "${NX_DIR}/install-nexus-fresh.sh" ]]; then
                    bash "${NX_DIR}/install-nexus-fresh.sh" --profile "${NEXUS_PROFILE:-2c8g}"
                else
                    run_install 2c8g fresh
                fi
                ;;
            7)
                require_root
                load_secrets
                check_ports_preflight "$NEXUS_ROOT"
                if is_stack_installed; then
                    check_ports_post "$NEXUS_ROOT"
                fi
                pause_enter
                ;;
            0) return 0 ;;
            *) warn "无效选项" ; sleep 1 ;;
        esac
    done
}

ops_restart_nexus() {
    step "重启 Nexus（Python）..."
    if [[ "$NX_RUNTIME" == "docker" ]]; then
        compose_cmd "$NEXUS_ROOT" restart nexus
    elif [[ "$NX_RUNTIME" == "supervisor" ]]; then
        supervisorctl restart nexus
    else
        error "未检测到运行中的 Nexus"
        return 1
    fi
    sleep 3
    verify_health "$NEXUS_ROOT" "重启" || true
}

ops_restart_stack() {
    step "重启 Compose 栈..."
    compose_cmd "$NEXUS_ROOT" restart
    sleep 5
    verify_health "$NEXUS_ROOT" "重启" || true
}

ops_stop_stack() {
    warn "将停止 Nexus 容器（MySQL/Redis 为外置服务，不受影响）"
    read -r -p "确认? [y/N]: " c
    [[ "$c" == "y" || "$c" == "Y" ]] || return 0
    compose_cmd "$NEXUS_ROOT" stop
    info "已停止"
}

ops_start_stack() {
    compose_cmd "$NEXUS_ROOT" up -d --remove-orphans
    verify_nexus_1panel_network "$NEXUS_ROOT" || return 1
    verify_health "$NEXUS_ROOT" "启动" || true
}

ops_logs() {
    local svc="${1:-nexus}"
    echo ""
    read -r -p "跟踪日志行数 [80]: " n
    n="${n:-80}"
    compose_cmd "$NEXUS_ROOT" logs --tail="$n" -f "$svc"
}

ops_status() {
    if [[ "$NX_RUNTIME" == "docker" ]]; then
        compose_cmd "$NEXUS_ROOT" ps
    elif [[ "$NX_RUNTIME" == "supervisor" ]]; then
        supervisorctl status nexus
    fi
    echo ""
    local port h code
    port="$(nexus_publish_port "$NEXUS_ROOT")"
    h=$(curl -sf "http://127.0.0.1:${port}/health" 2>/dev/null || echo "fail")
    info "/health → ${h}"
    local cname
    cname="$(nexus_container_name 2>/dev/null || true)"
    code=$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:${port}/app/install.html" 2>/dev/null || echo "000")
    if [[ -n "$cname" ]] && nexus_container_has_install_lock "$cname"; then
        if [[ "$code" == "404" ]]; then
            info "/app/install.html → 已归档 (HTTP 404)"
        else
            warn "/app/install.html → 应已归档但 HTTP ${code}"
        fi
    else
        info "/app/install.html → HTTP ${code}"
    fi
}

ops_backup_now() {
    NO_BACKUP=false
    backup_mysql "$NEXUS_ROOT"
}

ops_install_cron() {
    bash "${NX_DIR}/install_ops_cron.sh"
}

ops_update() {
    local args=()
    PRUNE_IMAGES=false
    NO_BACKUP=false
    NO_CACHE=false
    read -r -p "跳过 MySQL 备份? [y/N]: " nb
    [[ "$nb" == "y" || "$nb" == "Y" ]] && args+=(--no-backup)
    read -r -p "无缓存重建镜像? [y/N]: " nc
    [[ "$nc" == "y" || "$nc" == "Y" ]] && args+=(--no-cache)
    read -r -p "升级后清理悬空镜像? [y/N]: " pr
    [[ "$pr" == "y" || "$pr" == "Y" ]] && args+=(--prune)
    bash "${NX_DIR}/update.sh" "${args[@]}"
    pause_enter
}

require_installed() {
    if ! is_stack_installed; then
        warn "尚未安装，请先使用菜单 [1] 安装"
        pause_enter
        return 1
    fi
    require_root
    load_secrets
    load_saved_profile "$NEXUS_ROOT"
    detect_runtime
    return 0
}

menu_main() {
    load_secrets
    while true; do
        menu_header "运维菜单"
        cat <<'EOF'
  ── 安装 ──
  [1] 安装向导（新机 / 迁机 / 档位）
  [2] 全新安装 → /app/install.html

  ── 日常运维（需已安装）──
  [3] 状态 + 健康检查
  [4] 一键更新（pull + 重建镜像）★
  [5] 重启 Nexus（Python）
  [6] 查看 Nexus 日志
  [7] 启动 / 停止 Compose 栈
  [8] 重建镜像并启动（--build nexus）
  [9] 备份 MySQL
  [e] 安装巡检/备份 cron（health_monitor + db_backup）

  ── 其它 ──
  [a] 检查 Git 是否有更新
  [b] 端口 / 防火墙检查
  [c] 进入 Nexus 容器 shell
  [d] 1Panel 反代说明
  [0] 退出

EOF
        read -r -p "请选择: " choice
        case "$choice" in
            1) menu_install ;;
            2)
                require_root
                if is_stack_installed; then
                    warn "将执行全新安装（清除 nexus-state 卷内旧配置并重建容器）"
                    read -r -p "确认继续? [y/N]: " fresh_ok
                    [[ "$fresh_ok" == "y" || "$fresh_ok" == "Y" ]] || continue
                fi
                exec bash "${NX_DIR}/install-nexus-fresh.sh" --profile "${NEXUS_PROFILE:-2c8g}"
                ;;
            3)
                require_root
                if is_stack_installed; then
                    load_saved_profile "$NEXUS_ROOT"
                    detect_runtime
                    ops_status
                else
                    check_ports_preflight "$NEXUS_ROOT"
                fi
                pause_enter
                ;;
            4)
                require_installed || continue
                ops_update
                ;;
            5)
                require_installed || continue
                ops_restart_nexus
                pause_enter
                ;;
            6)
                require_installed || continue
                ops_logs nexus
                ;;
            7)
                require_installed || continue
                echo "  [1] 启动  [2] 停止  [3] 重启栈"
                read -r -p "选: " s
                case "$s" in
                    1) ops_start_stack ;;
                    2) ops_stop_stack ;;
                    3) ops_restart_stack ;;
                    *) warn "无效" ;;
                esac
                pause_enter
                ;;
            8)
                require_installed || continue
                read -r -p "无缓存重建? [y/N]: " nc
                if [[ "$nc" == "y" || "$nc" == "Y" ]]; then
                    compose_cmd "$NEXUS_ROOT" build --no-cache nexus
                fi
                compose_cmd "$NEXUS_ROOT" up -d --build --remove-orphans nexus
                verify_nexus_1panel_network "$NEXUS_ROOT" || true
                verify_health "$NEXUS_ROOT" "重建" || true
                pause_enter
                ;;
            9)
                require_installed || continue
                ops_backup_now
                pause_enter
                ;;
            e|E)
                require_root
                ops_install_cron
                pause_enter
                ;;
            a|A)
                require_root
                cmd_check
                pause_enter
                ;;
            b|B)
                require_root
                check_ports_preflight "$NEXUS_ROOT"
                is_stack_installed && check_ports_post "$NEXUS_ROOT" || true
                pause_enter
                ;;
            c|C)
                require_installed || continue
                compose_cmd "$NEXUS_ROOT" exec nexus bash || compose_cmd "$NEXUS_ROOT" exec nexus sh
                ;;
            d|D)
                info "1Panel → 网站 → 创建站点 ${NEXUS_DOMAIN}"
                info "反向代理: http://127.0.0.1:$(nexus_publish_port "$NEXUS_ROOT")"
                info "示例: ${NEXUS_ROOT}/deploy/1panel/openresty-nexus.conf.example"
                pause_enter
                ;;
            0) exit 0 ;;
            *) warn "无效选项"; sleep 1 ;;
        esac
    done
}

nx_main() {
    local sub="${1:-}"
    install_nx_cli
    load_secrets
    case "$sub" in
        ""|menu|god|ops|admin)
            # god/ops 已合并进主菜单，保留别名兼容
            [[ "$sub" == "god" || "$sub" == "ops" || "$sub" == "admin" ]] && \
                warn "「上帝菜单」已合并进 nx 主菜单，直接选对应项即可"
            menu_main
            ;;
        install) menu_install ;;
        update|upgrade)
            require_root
            shift || true
            exec bash "${NX_DIR}/update.sh" "$@"
            ;;
        install-fresh|fresh)
            require_root
            exec bash "${NX_DIR}/install-nexus-fresh.sh" "$@"
            ;;
        install-auto|auto)
            require_root
            if is_stack_installed; then
                warn "已安装，install-auto 将执行升级而非重复安装"
                exec bash "${NX_DIR}/update.sh"
            else
                run_install "${NEXUS_PROFILE:-2c8g}" ""
            fi
            ;;
        health)
            require_root
            is_stack_installed && ops_status || check_ports_preflight "$NEXUS_ROOT"
            ;;
        cron)
            require_root
            ops_install_cron
            ;;
        -h|--help)
            cat <<EOF
用法: nx [子命令]

  (无)            统一运维菜单（安装 + 升级 + 重启 + 日志）
  update          一键更新（等同 bash deploy/update.sh）
  install-fresh   全新安装（/app/install.html）
  install-auto    非交互安装（默认 2c8g）
  health          健康检查
  cron            安装 health_monitor + db_backup crontab

  god / ops       已合并进主菜单（兼容别名）

curl 入口:
  安装  curl -fsSL .../deploy/quick-install.sh | bash
  更新  curl -fsSL .../deploy/update.sh | bash
EOF
            ;;
        *)
            main "$@"
            ;;
    esac
}

chmod +x "${NX_DIR}/nx" 2>/dev/null || true
nx_main "$@"
