#!/bin/zsh
# ═══════════════════════════════════════════════════════════
#   Mihomo Kernel Manager — macOS
#   clash <command>   |   clash 进入交互菜单   |   clash help
# ═══════════════════════════════════════════════════════════

CONFIG_DIR="${HOME}/.config/mihomo"
CONFIG_FILE="${CONFIG_DIR}/config.yaml"
PID_FILE="${CONFIG_DIR}/mihomo.pid"
LOG_FILE="${CONFIG_DIR}/mihomo.log"
LINK_FILE="${CONFIG_DIR}/source.txt"     # 源 YAML 路径
SOURCE_DIR="${HOME}/Mihomo"              # 源配置目录（自动检测最新 YAML）
MIXED_PORT="7890"
API_PORT="9090"
MIHOMO_BIN="/opt/homebrew/bin/mihomo"

[[ -d "$CONFIG_DIR" ]] || mkdir -p "$CONFIG_DIR"

# ─── 颜色 ───
BOLD='\033[1m'; DIM='\033[2m'
GREEN='\033[0;32m'; BOLD_GREEN='\033[1;32m'
RED='\033[0;31m'; BOLD_RED='\033[1;31m'
YELLOW='\033[0;33m'; BOLD_YELLOW='\033[1;33m'
BLUE='\033[0;34m'; BOLD_BLUE='\033[1;34m'
PURPLE='\033[0;35m'; BOLD_PURPLE='\033[1;35m'
CYAN='\033[0;36m'; BOLD_CYAN='\033[1;36m'
WHITE='\033[1;37m'
NC='\033[0m'
SEP="${DIM}──────────────────────────────────────────${NC}"

# ─── 输出辅助 ───
info()  { echo "  ${CYAN}ℹ${NC} $*"; }
ok()    { echo "  ${GREEN}✓${NC} $*"; }
warn()  { echo "  ${YELLOW}⚠${NC} $*"; }
err()   { echo "  ${RED}✗${NC} $*"; }
dim()   { echo "  ${DIM}$*${NC}"; }
section(){ echo ""; echo "  ${BOLD}── $* ──${NC}"; }

# ─── 运行状态 ───
is_running() {
    [[ -f "$PID_FILE" ]] && pgrep -F "$PID_FILE" &>/dev/null
}

# ========== 源文件自动检测 ==========
# 优先级：link 固定路径 > SOURCE_DIR 最新 .yaml/.yml
auto_detect_source() {
    if [[ -f "$LINK_FILE" ]]; then
        local linked=$(cat "$LINK_FILE")
        if [[ -f "$linked" ]]; then
            echo "$linked"
            return 0
        fi
        warn "链接文件不存在: $linked，尝试自动检测..."
    fi
    if [[ -d "$SOURCE_DIR" ]]; then
        local latest=$(ls -t "$SOURCE_DIR"/*.yaml(N) "$SOURCE_DIR"/*.yml(N) 2>/dev/null | head -1)
        if [[ -n "$latest" && -f "$latest" ]]; then
            echo "$latest"
            return 0
        fi
    fi
    return 1
}

# ========== macOS 适配：复制源文件并做兼容转换（不改原件）==========
macos_adapt_config() {
    local src="${1:-}"
    if [[ -z "$src" ]]; then
        src=$(auto_detect_source)
    fi
    if [[ -z "$src" || ! -f "$src" ]]; then
        err "未找到 YAML 配置文件"
        dim "请把 .yaml 放到 $SOURCE_DIR，或用: clash link /path/to/file.yaml"
        return 1
    fi

    echo -n "  适配 macOS 配置 ... "
    cp "$src" "$CONFIG_FILE"

    # macOS 兼容修复
    sed -i '' '/^[[:space:]]*device: nikki[[:space:]]*$/d' "$CONFIG_FILE"
    sed -i '' '/^[[:space:]]*device: nikki$/d' "$CONFIG_FILE"
    sed -i '' 's/^\([[:space:]]*stack:\) system/\1 gvisor/' "$CONFIG_FILE"
    sed -i '' '/^[[:space:]]*auto-redirect: true/d' "$CONFIG_FILE"
    sed -i '' 's/  - tcp:\/\//  - /g' "$CONFIG_FILE"
    sed -i '' 's/  - udp:\/\//  - /g' "$CONFIG_FILE"

    ok "完成"
    dim "源文件   $src"
    dim "适配后   $CONFIG_FILE"
    return 0
}

# ========== 管理面板 ==========
# /ui 下可能有多个面板子目录（如 zashboard），自动定位并生成首页跳转
ui_url() {
    local ui_dir="$CONFIG_DIR/ui"
    if [[ -d "$ui_dir" ]]; then
        local dash
        dash=$(find "$ui_dir" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sort | head -1)
        if [[ -n "$dash" ]]; then
            echo "http://127.0.0.1:${API_PORT}/ui/$(basename "$dash")/"
            return 0
        fi
    fi
    echo "http://127.0.0.1:${API_PORT}/ui"
}

ensure_ui_index() {
    local ui_dir="$CONFIG_DIR/ui"
    [[ -d "$ui_dir" ]] || return 0
    local dash
    dash=$(find "$ui_dir" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sort | head -1)
    [[ -z "$dash" ]] && return 0
    local dash_name=$(basename "$dash")
    local index_file="$ui_dir/index.html"
    if [[ ! -f "$index_file" ]]; then
        cat > "$index_file" <<EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=./${dash_name}/">
<title>Mihomo Dashboard</title>
</head>
<body>
<p>正在打开面板 <a href="./${dash_name}/">${dash_name}</a> ...</p>
</body>
</html>
EOF
        info "已生成面板首页跳转: $index_file"
    fi
}

# ========== 残留网络状态检测 ==========
# 返回 0 = 存在 mihomo 残留进程 / 残留 TUN 劫持 / 系统代理 / DNS 劫持
network_leftovers() {
    pgrep -l mihomo >/dev/null 2>&1 && return 0

    local dev
    for dev in $(ifconfig -l 2>/dev/null); do
        [[ "$dev" != utun* ]] && continue
        local idx="${dev#utun}"
        [[ "$idx" != <-> ]] && continue
        if ifconfig "$dev" 2>/dev/null | grep -qE "inet 198\.18\."; then
            return 0
        fi
        if netstat -rn -f inet 2>/dev/null | grep -qE "198\.18\.[[:space:]]+.*[[:space:]]+$dev"; then
            return 0
        fi
        (( idx >= 1024 )) && return 0
    done

    local hijacked=0
    while IFS= read -r service; do
        local clean=$(printf '%s' "$service" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
        [[ -z "$clean" ]] && continue
        local wp=$(networksetup -getwebproxy "$clean" 2>/dev/null)
        local sp=$(networksetup -getsocksfirewallproxy "$clean" 2>/dev/null)
        if echo "$wp$sp" | grep -qE "Server: 127\.0\.0\.1" && echo "$wp$sp" | grep -qE "Port: ${MIXED_PORT}"; then
            hijacked=1
            break
        fi
    done < <(networksetup -listallnetworkservices 2>/dev/null | tail -n +2)
    [[ $hijacked -eq 1 ]] && return 0

    scutil --dns 2>/dev/null | grep -qE "nameserver\[[0-9]+\].*(127\.0\.0\.1|198\.18\.)" && return 0
    return 1
}

# ========== 网络恢复（TUN/路由/代理/DNS 全面清理）==========
network_restore() {
    local verbose=${1:-true}

    $verbose && section "网络恢复"

    # 1. 清理残留 mihomo 进程
    if pgrep -l mihomo >/dev/null 2>&1; then
        $verbose && warn "发现残留进程，正在清理..."
        sudo pkill -9 mihomo 2>/dev/null
        rm -f "$PID_FILE"
    fi

    # 2. 清理 mihomo 残留 TUN / 全量劫持路由
    #    放宽识别：fake-IP 网关只要是 198.18.x 段都算（不限于 198.18.0.1），
    #    并无条件删除 0.0.0.0/1 + 128.0.0.0/1 这两条黑洞路由，防止残留导致断网
    local tun_list=$(ifconfig -l 2>/dev/null)
    # fake-IP 网关段（默认 198.18.x，放宽不再只认 198.18.0.1）
    local fake_gws=$(netstat -rn -f inet 2>/dev/null | awk '$4 ~ /^utun[0-9]+$/ && $2 ~ /^198\.18\./ {print $2}' | sort -u)
    local route_devs=$(netstat -rn -f inet 2>/dev/null | awk '$4 ~ /^utun[0-9]+$/ && $2 ~ /^198\.18\./ {print $4}' | sort -u)
    local mihomo_tuns=""
    for dev in ${(s: :)tun_list}; do
        [[ "$dev" != utun* ]] && continue
        local idx="${dev#utun}"
        [[ "$idx" != <-> ]] && continue
        if ifconfig "$dev" 2>/dev/null | grep -qE "inet 198\.18\."; then
            mihomo_tuns+=" $dev"
            continue
        fi
        if [[ -n "$route_devs" ]] && echo "$route_devs" | grep -qx "$dev"; then
            mihomo_tuns+=" $dev"
            continue
        fi
        (( idx >= 1024 )) && mihomo_tuns+=" $dev"
    done

    # 无条件清理全量劫持路由（0.0.0.0/1 + 128.0.0.0/1），几乎必定是 mihomo 创建
    for gw in ${(s: :)fake_gws}; do
        sudo route -n delete -net 0.0.0.0/1 "$gw" 2>/dev/null
        sudo route -n delete -net 128.0.0.0/1 "$gw" 2>/dev/null
        sudo route -n delete -net 198.18.0.0/16 "$gw" 2>/dev/null
    done
    # 兜底：常见默认网关组合，防止识别遗漏留下黑洞
    sudo route -n delete -net 0.0.0.0/1 198.18.0.1 2>/dev/null
    sudo route -n delete -net 128.0.0.0/1 198.18.0.1 2>/dev/null

    for dev in ${(s: :)mihomo_tuns}; do
        $verbose && echo -n "  清理残留 TUN $dev ... "
        sudo ifconfig "$dev" down 2>/dev/null
        sudo ifconfig "$dev" destroy 2>/dev/null
        $verbose && echo "${GREEN}✓${NC}"
    done

    # 3. 关闭系统 HTTP/HTTPS/SOCKS 代理（遍历所有网络服务）
    while IFS= read -r service; do
        local clean=$(printf '%s' "$service" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
        [[ -z "$clean" ]] && continue
        local wp=$(networksetup -getwebproxy "$clean" 2>/dev/null)
        local sp=$(networksetup -getsocksfirewallproxy "$clean" 2>/dev/null)
        if echo "$wp$sp" | grep -qE "Server: 127\.0\.0\.1" && echo "$wp$sp" | grep -qE "Port: ${MIXED_PORT}"; then
            $verbose && echo -n "  关闭系统代理 ($clean) ... "
            sudo networksetup -setwebproxystate "$clean" off 2>/dev/null
            sudo networksetup -setsecurewebproxystate "$clean" off 2>/dev/null
            sudo networksetup -setsocksfirewallproxystate "$clean" off 2>/dev/null
            $verbose && echo "${GREEN}✓${NC}"
        fi
    done < <(networksetup -listallnetworkservices 2>/dev/null | tail -n +2)

    # 4. 刷新 DNS 缓存
    $verbose && echo -n "  刷新 DNS 缓存 ... "
    sudo dscacheutil -flushcache 2>/dev/null
    sudo killall -HUP mDNSResponder 2>/dev/null
    $verbose && echo "${GREEN}✓${NC}"

    # 5. 还原系统 DNS（如果被 mihomo 指到 127.0.0.1 / 198.18.x）
    if scutil --dns 2>/dev/null | grep -qE "nameserver\[[0-9]+\].*(127\.0\.0\.1|198\.18\.)"; then
        $verbose && echo -n "  还原系统 DNS ... "
        while IFS= read -r service; do
            local clean=$(printf '%s' "$service" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
            [[ -z "$clean" ]] && continue
            if networksetup -getdnsservers "$clean" 2>/dev/null | grep -qE "^(127\.0\.0\.1|198\.18\.)"; then
                sudo networksetup -setdnsservers "$clean" empty 2>/dev/null
            fi
        done < <(networksetup -listallnetworkservices 2>/dev/null | tail -n +2)
        sudo dscacheutil -flushcache 2>/dev/null
        sudo killall -HUP mDNSResponder 2>/dev/null
        $verbose && echo "${GREEN}✓${NC}"
    fi

    $verbose && echo ""
    $verbose && ok "网络已恢复"
}

# ========== 网络诊断 ==========
network_health_check() {
    local issues=0
    section "网络诊断"

    if nslookup baidu.com >/dev/null 2>&1; then
        ok "DNS 解析正常 (baidu.com)"
    else
        err "DNS 解析失败"
        issues=1
    fi

    if ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1; then
        ok "外网连通 (8.8.8.8)"
    else
        err "外网不可达"
        issues=1
    fi

    local tun_count=$(ifconfig -l 2>/dev/null | tr ' ' '\n' | grep -c "^utun")
    local tun_high=0
    local dev
    for dev in $(ifconfig -l 2>/dev/null); do
        [[ "$dev" != utun* ]] && continue
        local idx="${dev#utun}"
        [[ "$idx" != <-> ]] && continue
        (( idx >= 1024 )) && (( tun_high++ ))
    done
    if [[ $tun_high -eq 0 ]]; then
        ok "TUN 接口 ${tun_count} 个，无残留"
    else
        warn "TUN ${tun_count} 个（${tun_high} 个高编号残留）"
        issues=1
    fi

    if [[ $issues -eq 1 ]]; then
        warn "网络可能有异常，试试: clash cleanup"
    else
        ok "网络一切正常"
    fi
}

# ========== 启动 ==========
cmd_start() {
    local src="${1:-}"
    local do_adapt=true

    if [[ -n "$src" ]]; then
        if [[ "$src" == "$CONFIG_FILE" ]] || [[ "$src" == "$(cat "$LINK_FILE" 2>/dev/null)" ]]; then
            do_adapt=false
        fi
    fi
    if [[ -z "$src" ]]; then
        src=$(auto_detect_source)
    fi

    if $do_adapt && [[ "$src" != "$CONFIG_FILE" ]]; then
        macos_adapt_config "$src" || return 1
    elif [[ ! -f "$CONFIG_FILE" ]]; then
        err "配置文件不存在: $CONFIG_FILE"
        dim "试试: clash link /path/to/your.yaml"
        return 1
    fi

    if is_running; then
        warn "mihomo 已经在运行了"
        return 0
    fi

    # 启动前清理上次异常退出残留（旧 TUN/路由会继续劫持全部流量）
    if network_leftovers; then
        echo ""
        info "检测到上次残留网络状态，先清理 ..."
        network_restore false
    fi

    echo ""
    echo -n "  启动中 ... "
    nohup sudo "$MIHOMO_BIN" -d "$CONFIG_DIR" -f "$CONFIG_FILE" > "$LOG_FILE" 2>&1 &
    local sudo_pid=$!
    sleep 1
    # 解析 mihomo 真实 PID（sudo 的子进程），PID 文件记它，stop 才能精确杀
    local mihomo_pid=$(pgrep -P "$sudo_pid" 2>/dev/null | head -1)
    echo "${mihomo_pid:-$sudo_pid}" > "$PID_FILE"

    if is_running; then
        ok "已就绪"
        ensure_ui_index
        echo ""
        printf "  ${DIM}%-10s${NC} ${CYAN}127.0.0.1:${MIXED_PORT}${NC}  ${DIM}(HTTP/SOCKS5)${NC}\n" "代理端口"
        printf "  ${DIM}%-10s${NC} ${CYAN}127.0.0.1:${API_PORT}${NC}\n" "API 控制"
        printf "  ${DIM}%-10s${NC} ${CYAN}$(ui_url)${NC}\n" "管理面板"
        echo ""
    else
        err "启动失败"
        dim "查看日志: tail $LOG_FILE"
        rm -f "$PID_FILE"
        return 1
    fi
}

# ========== 停止 ==========
cmd_stop() {
    if ! is_running; then
        warn "mihomo 没有在运行"
        # 进程没了但可能残留 TUN/路由/代理（例如被强杀），顺手清理
        if network_leftovers; then
            echo ""
            info "检测到残留网络状态，正在清理 ..."
            network_restore true
            echo ""
            network_health_check
        fi
        return 0
    fi

    local pid=$(cat "$PID_FILE")
    echo ""
    echo -n "  停止中 ... "
    # 直接给 mihomo 发 SIGTERM（PID 文件记的是 sudo，按进程名杀最稳）
    sudo pkill -TERM -x mihomo 2>/dev/null
    sudo kill "$pid" 2>/dev/null   # 兜底：也通知 sudo 进程

    for i in {1..10}; do
        if ! pgrep -x mihomo >/dev/null 2>&1; then
            ok "已停止"
            rm -f "$PID_FILE"
            echo ""
            network_restore false
            network_health_check
            return 0
        fi
        sleep 0.5
    done

    echo ""
    warn "超时，强制终止..."
    sudo pkill -9 -x mihomo 2>/dev/null
    sleep 0.5
    rm -f "$PID_FILE"

    if pgrep -x mihomo >/dev/null 2>&1; then
        err "停止失败，残留进程仍在运行"
        dim "试试: sudo pkill -9 mihomo"
        return 1
    fi

    warn "已强制停止"
    info "正在恢复网络 ..."
    network_restore true
    echo ""
    network_health_check
}

# ========== 重启 / 热重载 ==========
cmd_restart() {
    cmd_stop
    sleep 1
    cmd_start "$@"
}

cmd_reload() {
    local cfg="${1:-$CONFIG_FILE}"
    if ! is_running; then
        warn "mihomo 没在运行，直接启动"
        cmd_start "$cfg"
        return $?
    fi
    if [[ ! -f "$cfg" ]]; then
        err "配置文件不存在: $cfg"
        return 1
    fi
    echo -n "  热重载配置 ... "
    if curl -s -X PUT "http://127.0.0.1:${API_PORT}/configs" \
        -H "Content-Type: application/json" \
        -d "{\"path\":\"${cfg}\"}" > /dev/null 2>&1; then
        ok "成功"
    else
        err "API 不可达，尝试重启..."
        cmd_restart "$cfg"
    fi
}

# ========== 状态 ==========
cmd_status() {
    if is_running; then
        local pid=$(cat "$PID_FILE")
        echo ""
        echo "  ${BOLD_GREEN}● 运行中${NC}  ${DIM}PID: $pid${NC}"
        echo "  $SEP"
        printf "  ${DIM}%-10s${NC} ${CYAN}127.0.0.1:${MIXED_PORT}${NC} (HTTP/SOCKS5)\n" "代理端口"
        printf "  ${DIM}%-10s${NC} ${CYAN}127.0.0.1:${API_PORT}${NC}\n" "API 端口"
        printf "  ${DIM}%-10s${NC} ${CYAN}$(ui_url)${NC}\n" "管理面板"
        printf "  ${DIM}%-10s${NC} %s\n" "配置文件" "$CONFIG_FILE"
        printf "  ${DIM}%-10s${NC} %s\n" "日志文件" "$LOG_FILE"
        local src=$(cat "$LINK_FILE" 2>/dev/null || auto_detect_source 2>/dev/null)
        [[ -n "$src" ]] && printf "  ${DIM}%-10s${NC} %s\n" "源文件" "$src"
        echo ""
    else
        echo ""
        echo "  ${BOLD_RED}○ 已停止${NC}"
        echo "  $SEP"
        dim "mihomo 当前未运行"
        echo ""
        rm -f "$PID_FILE"
    fi
}

# ========== 链接源配置（查看/设置，合并原 import）==========
cmd_link() {
    local src="${1:-}"
    if [[ -z "$src" ]]; then
        echo ""
        section "源文件链接"
        if [[ -f "$LINK_FILE" ]]; then
            info "当前链接: $(cat "$LINK_FILE")"
        else
            local detected=$(auto_detect_source)
            if [[ -n "$detected" ]]; then
                info "自动检测: $detected"
            else
                warn "未检测到源文件"
            fi
        fi
        echo ""
        echo -n "  请输入 YAML 文件路径 ${DIM}(Enter 取消)${NC}: "
        read src
        [[ -z "$src" ]] && { dim "已取消"; return 0; }
        src=$(echo "$src" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/^"//;s/"$//')
    fi

    if [[ ! -f "$src" ]]; then
        err "文件不存在: $src"
        return 1
    fi

    echo "$src" > "$LINK_FILE"
    ok "已链接"
    dim "源文件   $src"
    echo ""
    echo -n "  立即适配并启动? (y/n) "
    read -q ans
    echo ""
    if [[ "$ans" == "y" ]]; then
        macos_adapt_config "$src" || return 1
        if is_running; then
            cmd_restart
        else
            cmd_start
        fi
    fi
}

# ========== 日志 / 编辑 / 面板 / 修复 / 诊断 ==========
cmd_log() {
    if [[ -f "$LOG_FILE" ]]; then
        echo ""
        section "实时日志  (Ctrl+C 退出)"
        tail -f "$LOG_FILE"
    else
        warn "日志文件不存在"
    fi
}

cmd_edit() {
    info "打开编辑器: $CONFIG_FILE"
    ${EDITOR:-vim} "$CONFIG_FILE"
}

cmd_open() {
    if is_running; then
        ensure_ui_index
        local url=$(ui_url)
        open "$url"
        ok "已打开管理面板"
        dim "$url"
    else
        warn "mihomo 未运行，请先启动"
    fi
}

cmd_cleanup() {
    network_restore true
}

cmd_doctor() {
    network_health_check
}

# ========== 关闭 Clash Verge 后台服务 ==========
cmd_verge_off() {
    echo ""
    section "关闭 Clash Verge"
    local svc_pid=$(pgrep -f "clash-verge-service" 2>/dev/null)
    if [[ -n "$svc_pid" ]]; then
        info "发现 Clash Verge 服务 (PID: $svc_pid)"
        echo -n "  正在停止 ... "
        sudo kill "$svc_pid" 2>/dev/null
        sleep 1
        if pgrep -f "clash-verge-service" >/dev/null 2>&1; then
            sudo kill -9 "$svc_pid" 2>/dev/null
        fi
        ok "已停止"
    else
        ok "Clash Verge 服务未运行"
    fi

    echo ""
    echo -n "  是否同时卸载开机自启? (y/n) "
    read -q ans
    echo ""
    if [[ "$ans" == "y" ]]; then
        sudo /bin/launchctl unload /Library/LaunchDaemons/io.github.clash-verge-rev.clash-verge-rev.plist 2>/dev/null
        ok "已卸载开机自启"
    fi
    echo ""
    ok "现在可以纯用 clash 脚本管理了"
    echo ""
}

# ========== 帮助 ==========
show_help() {
    echo ""
    echo "  ${BOLD_PURPLE}Mihomo Kernel Manager${NC}  ${DIM}— macOS${NC}"
    echo "  $SEP"
    echo ""
    echo "  ${BOLD}用法:${NC}"
    echo "    ${CYAN}clash <command>${NC}   执行子命令"
    echo "    ${CYAN}clash${NC}             进入交互菜单"
    echo "    ${CYAN}clash help${NC}        显示本帮助"
    echo ""
    echo "  ${BOLD}核心:${NC}"
    printf "    ${CYAN}%-14s${NC} %s\n" "start [file]" "启动（自动适配 macOS 配置）"
    printf "    ${CYAN}%-14s${NC} %s\n" "stop" "停止并恢复网络"
    printf "    ${CYAN}%-14s${NC} %s\n" "restart" "重启"
    printf "    ${CYAN}%-14s${NC} %s\n" "status" "查看运行状态"
    printf "    ${CYAN}%-14s${NC} %s\n" "reload [file]" "热重载配置"
    printf "    ${CYAN}%-14s${NC} %s\n" "open" "打开管理面板"
    printf "    ${CYAN}%-14s${NC} %s\n" "log" "实时日志"
    echo ""
    echo "  ${BOLD}配置:${NC}"
    printf "    ${CYAN}%-14s${NC} %s\n" "link [file]" "查看/设置源 YAML（含原 import）"
    printf "    ${CYAN}%-14s${NC} %s\n" "edit" "编辑当前配置"
    echo ""
    echo "  ${BOLD}网络:${NC}"
    printf "    ${CYAN}%-14s${NC} %s\n" "cleanup" "网络修复（清理残留 TUN/路由/代理/DNS）"
    printf "    ${CYAN}%-14s${NC} %s\n" "doctor" "网络诊断"
    echo ""
    echo "  ${BOLD}系统:${NC}"
    printf "    ${CYAN}%-14s${NC} %s\n" "verge-off" "关闭 Clash Verge 后台服务"
    echo ""
    echo "  ${BOLD}示例:${NC}"
    dim "clash start"
    dim "clash link ~/Mihomo/config.yaml"
    dim "clash cleanup"
    echo ""
}

# ========== 交互菜单 ==========
show_menu() {
    clear
    echo ""
    echo "  ${BOLD_PURPLE}Mihomo Kernel Manager${NC}  ${DIM}— macOS${NC}"
    echo "  $SEP"

    if is_running; then
        printf "  ${BOLD_GREEN}● 运行中${NC}  ${DIM}PID: %s${NC}  ${DIM}代理: %s${NC}  ${DIM}API: %s${NC}\n" \
            "$(cat "$PID_FILE" 2>/dev/null)" "${MIXED_PORT}" "${API_PORT}"
    else
        echo "  ${BOLD_RED}○ 已停止${NC}"
    fi
    echo ""

    echo "  ${BOLD}1${NC} 启动        ${BOLD}5${NC} 状态"
    echo "  ${BOLD}2${NC} 停止        ${BOLD}6${NC} 实时日志"
    echo "  ${BOLD}3${NC} 打开面板    ${BOLD}7${NC} 热重载"
    echo "  ${BOLD}4${NC} 重启        ${BOLD}8${NC} 网络修复"
    echo "  ${BOLD}0${NC} 退出"
    echo ""
    echo -n "  ${BOLD}❯${NC} "
}

interactive_menu() {
    while true; do
        show_menu
        read choice
        echo ""
        case "$choice" in
            1) cmd_start ;;
            2) cmd_stop ;;
            3) cmd_open ;;
            4) cmd_restart ;;
            5) cmd_status ;;
            6) cmd_log ;;
            7) cmd_reload ;;
            8) cmd_cleanup ;;
            0|q|Q)
                echo "  ${DIM}再见 👋${NC}"
                echo ""
                break
                ;;
            *) warn "无效选项，请输入 0-8" ;;
        esac
        echo ""
        echo -n "  按 Enter 返回菜单..."
        read
    done
}

# ========== 入口 ==========
case "${1:-}" in
    start|s)     cmd_start "$2" ;;
    stop)        cmd_stop ;;
    restart|r)   cmd_restart "$2" ;;
    reload|rl)   cmd_reload "$2" ;;
    status|st)   cmd_status ;;
    log|l)       cmd_log ;;
    link|lk)     cmd_link "$2" ;;
    open|o)      cmd_open ;;
    edit|e)      cmd_edit ;;
    cleanup|c)   cmd_cleanup ;;
    doctor|d)    cmd_doctor ;;
    verge-off)   cmd_verge_off ;;
    help|-h|--help|h) show_help ;;
    *) interactive_menu ;;
esac
