#!/usr/bin/env bash
# ============================================
# HY2.sh - Hysteria 2 一键安装脚本 (多系统增强修复版)
# 功能: 自动安装 + 自签证书 + 交互/自动配置
# 用法: bash HY2.sh [auto]
# ============================================
set -e

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; PURPLE='\033[0;35m'; CYAN='\033[0;36m'
WHITE='\033[1;37m'; NC='\033[0m'

info()    { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
error()   { echo -e "${RED}[ERROR]${NC} $1"; }

HY2_BIN="/usr/local/bin/hysteria"
HY2_CONF="/etc/hysteria/config.yaml"
HY2_UNIT="/etc/systemd/system/hysteria-server.service"
CERT_PATH="/etc/hysteria/cert.crt"
KEY_PATH="/etc/hysteria/private.key"

banner() {
    echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║${NC}          ${PURPLE}Hysteria 2 一键安装脚本 (自动签名版)${NC}              ${CYAN}║${NC}"
    echo -e "${CYAN}║${NC}              ${WHITE}支持自签证书 / 交互或自动模式${NC}                    ${CYAN}║${NC}"
    echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
    echo
}

check_root() {
    if [[ $EUID -ne 0 ]]; then
        error "请使用 root 权限运行此脚本"
        exit 1
    fi
}

detect_os() {
    if [[ -f /etc/os-release ]]; then
        # shellcheck disable=SC1091
        . /etc/os-release
        OS=${ID:-unknown}
        VER=${VERSION_ID:-}
        OS_LIKE=${ID_LIKE:-}
    else
        error "无法检测操作系统"
        exit 1
    fi
    info "检测到系统: ${WHITE}$OS $VER${NC}"
}

pkg_mgr() {
    local id_l like_l
    id_l=$(echo "${OS}" | tr '[:upper:]' '[:lower:]')
    like_l=$(echo "${OS_LIKE}" | tr '[:upper:]' '[:lower:]')

    case "$id_l" in
        ubuntu|debian|linuxmint|kali|raspbian|pop|elementary|zorin)
            echo apt; return ;;
        fedora|nobara)
            echo dnf; return ;;
        centos|rhel|rocky|almalinux|alinux|anolis|opencloudos|tencentos|ctyunos|amzn|ol|openeuler|euleros|kylin|uos|opencloud)
            if command -v dnf >/dev/null 2>&1; then echo dnf; else echo yum; fi
            return ;;
        arch|manjaro|endeavouros|garuda)
            echo pacman; return ;;
        alpine)
            echo apk; return ;;
    esac

    case "$like_l" in
        *debian*|*ubuntu*) echo apt; return ;;
        *rhel*|*fedora*|*centos*) 
            if command -v dnf >/dev/null 2>&1; then echo dnf; else echo yum; fi
            return ;;
        *arch*) echo pacman; return ;;
    esac

    if command -v apt-get >/dev/null 2>&1; then echo apt
    elif command -v dnf >/dev/null 2>&1; then echo dnf
    elif command -v yum >/dev/null 2>&1; then echo yum
    elif command -v pacman >/dev/null 2>&1; then echo pacman
    elif command -v apk >/dev/null 2>&1; then echo apk
    else echo unknown
    fi
}

detect_arch() {
    case "$(uname -m)" in
        x86_64|amd64) echo amd64 ;;
        aarch64|arm64) echo arm64 ;;
        armv7l|armv7*) echo arm ;;
        armv6l|armv6*) echo arm ;;
        i386|i686) echo 386 ;;
        s390x) echo s390x ;;
        riscv64) echo riscv64 ;;
        mips64el|mipsel) echo mipsle ;;
        *) echo unknown ;;
    esac
}

probe_url() {
    local url="$1"
    curl -fsS -o /dev/null -m 4 --connect-timeout 3 -L "$url" 2>/dev/null
}

detect_location() {
    info "正在检测服务器位置..."
    local ip country raw
    ip=$(curl -fsS -m 5 https://ipinfo.io/ip 2>/dev/null \
        || curl -fsS -m 5 http://ipinfo.io/ip 2>/dev/null \
        || curl -fsS -m 5 https://api.ipify.org 2>/dev/null \
        || curl -fsS -m 5 https://ifconfig.me 2>/dev/null \
        || echo "")
    country=""
    if [[ -n "$ip" ]]; then
        country=$(curl -fsS -m 5 "https://ipinfo.io/${ip}/country" 2>/dev/null \
            || curl -fsS -m 5 "http://ipinfo.io/${ip}/country" 2>/dev/null \
            || echo "")
        country=$(echo "$country" | tr -d '[:space:]' | tr '[:lower:]' '[:upper:]')
    fi
    if [[ "$country" != "CN" ]]; then
        raw=$(curl -fsS -m 5 https://myip.ipip.net 2>/dev/null || curl -fsS -m 5 http://myip.ipip.net 2>/dev/null || echo "")
        if echo "$raw" | grep -qE '中国|China'; then
            country="CN"
        fi
    fi
    if [[ "$country" != "CN" ]]; then
        raw=$(curl -fsS -m 5 https://cip.cc 2>/dev/null || curl -fsS -m 5 http://cip.cc 2>/dev/null || echo "")
        if echo "$raw" | grep -qE '中国|China|CN'; then
            country="CN"
        fi
    fi

    if [[ "$country" == "CN" ]]; then
        LOCATION="china"
        warning "检测到中国大陆服务器，将优先使用国内镜像"
    else
        LOCATION="global"
        info "检测到海外服务器，将使用官方源"
    fi

    info "正在检测伪装站点可达性..."
    if probe_url "https://www.baidu.com" && ! probe_url "https://www.google.com"; then
        MASQ_REGION="china"
        warning "本机访问不了海外站，伪装将使用国内站点"
    elif [[ "$LOCATION" == "china" ]]; then
        MASQ_REGION="china"
        info "伪装区域: 国内站点"
    elif probe_url "https://www.google.com" || probe_url "https://www.cloudflare.com"; then
        MASQ_REGION="global"
        info "伪装区域: 海外站点"
    else
        MASQ_REGION="china"
        warning "海外站探测失败，伪装默认改用国内站点"
    fi
}

install_deps() {
    info "[1/5] 正在安装依赖..."
    local mgr
    mgr=$(pkg_mgr)
    info "包管理器: ${WHITE}$mgr${NC}"

    case "$mgr" in
        apt)
            export DEBIAN_FRONTEND=noninteractive
            apt-get update -qq || true
            apt-get install -y -qq curl wget openssl ca-certificates jq || {
                error "apt 安装依赖失败"; exit 1
            }
            ;;
        dnf)
            dnf install -y -q epel-release 2>/dev/null || true
            dnf install -y -q curl wget openssl ca-certificates || {
                error "dnf 安装依赖失败"; exit 1
            }
            dnf install -y -q jq 2>/dev/null || true
            ;;
        yum)
            yum install -y -q epel-release 2>/dev/null || true
            yum install -y -q curl wget openssl ca-certificates || {
                error "yum 安装依赖失败"; exit 1
            }
            yum install -y -q jq 2>/dev/null || true
            ;;
        pacman)
            pacman -Sy --noconfirm curl wget openssl ca-certificates jq || {
                error "pacman 安装依赖失败"; exit 1
            }
            ;;
        apk)
            apk add --no-cache curl wget openssl ca-certificates jq || {
                error "apk 安装依赖失败"; exit 1
            }
            ;;
        *)
            error "不支持的系统，未找到 apt/dnf/yum/pacman/apk"
            exit 1
            ;;
    esac

    command -v curl >/dev/null 2>&1 || { error "curl 安装失败"; exit 1; }
    command -v openssl >/dev/null 2>&1 || { error "openssl 安装失败"; exit 1; }
    success "依赖安装完成"
}

download_file() {
    local url="$1" dest="$2"
    if curl -fsSL --connect-timeout 15 --max-time 180 -o "$dest" "$url"; then
        [[ -s "$dest" ]] && return 0
    fi
    if command -v wget >/dev/null 2>&1; then
        wget -q --timeout=30 --tries=2 -O "$dest" "$url" && [[ -s "$dest" ]] && return 0
    fi
    rm -f "$dest"
    return 1
}

install_hysteria_official() {
    local script_tmp urls u
    script_tmp=$(mktemp)
    urls=()
    if [[ "$LOCATION" == "china" ]]; then
        urls+=(
            "https://ghfast.top/https://raw.githubusercontent.com/apernet/hysteria/master/scripts/install.sh"
            "https://mirror.ghproxy.com/https://raw.githubusercontent.com/apernet/hysteria/master/scripts/install.sh"
            "https://get.hy2.sh/"
            "https://get.hy2.io/"
        )
    else
        urls+=(
            "https://get.hy2.sh/"
            "https://get.hy2.io/"
            "https://raw.githubusercontent.com/apernet/hysteria/master/scripts/install.sh"
        )
    fi

    for u in "${urls[@]}"; do
        info "尝试官方安装脚本: $u"
        if download_file "$u" "$script_tmp"; then
            HYSTERIA_USER=root bash "$script_tmp" || true
            rm -f "$script_tmp"
            if [[ -x "$HY2_BIN" ]] || command -v hysteria >/dev/null 2>&1; then
                return 0
            fi
        fi
    done
    rm -f "$script_tmp"
    return 1
}

install_hysteria_binary() {
    local arch file tmp urls u
    arch=$(detect_arch)
    if [[ "$arch" == "unknown" ]]; then
        error "不支持的 CPU 架构: $(uname -m)"
        return 1
    fi
    file="hysteria-linux-${arch}"
    tmp=$(mktemp)
    urls=(
        "https://download.hysteria.network/app/latest/${file}"
        "https://github.com/apernet/hysteria/releases/latest/download/${file}"
        "https://ghfast.top/https://github.com/apernet/hysteria/releases/latest/download/${file}"
        "https://mirror.ghproxy.com/https://github.com/apernet/hysteria/releases/latest/download/${file}"
    )

    for u in "${urls[@]}"; do
        info "尝试直接下载二进制: $u"
        if download_file "$u" "$tmp"; then
            install -m 755 "$tmp" "$HY2_BIN"
            rm -f "$tmp"
            return 0
        fi
    done
    rm -f "$tmp"
    return 1
}

install_hysteria() {
    info "[2/5] 正在安装 Hysteria 2..."

    if command -v getenforce >/dev/null 2>&1 && [[ "$(getenforce 2>/dev/null)" == "Enforcing" ]]; then
        warning "检测到 SELinux Enforcing；若出现 SEContext 提示通常可忽略"
    fi

    if [[ -x "$HY2_BIN" ]] || command -v hysteria >/dev/null 2>&1; then
        info "检测到已安装的 Hysteria，跳过下载"
    else
        if ! install_hysteria_official; then
            warning "官方脚本安装失败，改用二进制直装..."
            if ! install_hysteria_binary; then
                error "Hysteria 2 安装失败（官方脚本与二进制均失败）"
                exit 1
            fi
        fi
    fi

    if [[ -x "$HY2_BIN" ]]; then
        export PATH="/usr/local/bin:$PATH"
    elif command -v hysteria >/dev/null 2>&1; then
        HY2_BIN=$(command -v hysteria)
    else
        error "未找到 hysteria 可执行文件"
        exit 1
    fi

    if command -v restorecon >/dev/null 2>&1; then
        restorecon -v "$HY2_BIN" 2>/dev/null || true
        restorecon -v /etc/systemd/system/hysteria-server.service 2>/dev/null || true
    fi

    local ver
    ver=$($HY2_BIN version 2>/dev/null | tr -d '\r' | grep -Eo 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
    success "Hysteria 2 安装完成${ver:+: $ver}"
}

# 🛠️ 修复点：彻底消除 Shell 进程替换的兼容性隐患，严格设置 CERT_PATH 变量
generate_selfsigned_cert() {
    local domain=$1
    local cert_dir="/etc/hysteria"
    mkdir -p "$cert_dir"
    info "正在生成自签名证书 (域名: $domain)..."

    CERT_PATH="$cert_dir/cert.crt"
    KEY_PATH="$cert_dir/private.key"

    # 生成临时 ecparam 参数文件，兼容标准 sh/bash
    local param_file
    param_file=$(mktemp)
    openssl ecparam -name prime256v1 -out "$param_file" 2>/dev/null || true

    if [[ -s "$param_file" ]] && openssl req -x509 -nodes -days 3650 -newkey ec:"$param_file" \
        -keyout "$KEY_PATH" -out "$CERT_PATH" \
        -subj "/CN=$domain" \
        -addext "subjectAltName=DNS:${domain},DNS:*.${domain}" 2>/dev/null; then
        rm -f "$param_file"
    else
        rm -f "$param_file"
        if ! openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
            -keyout "$KEY_PATH" -out "$CERT_PATH" \
            -subj "/CN=$domain" 2>/dev/null; then
            error "生成自签名证书失败"
            exit 1
        fi
    fi

    chmod 600 "$KEY_PATH"
    chmod 644 "$CERT_PATH"
    chown root:root "$KEY_PATH" "$CERT_PATH" 2>/dev/null || true
    success "自签名证书已生成"
}

normalize_url() {
    local u="$1" fallback="$2"
    u=$(echo "$u" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    if [[ -z "$u" ]]; then
        echo "$fallback"
        return
    fi
    if [[ ! "$u" =~ ^https?:// ]]; then
        u="https://${u}"
    fi
    echo "$u"
}

validate_port() {
    local p="$1"
    if ! [[ "$p" =~ ^[0-9]+$ ]] || (( p < 1 || p > 65535 )); then
        error "无效端口: $p"
        exit 1
    fi
}

choose_masquerade() {
    local region_default region_choice site_choice default_masq default_sni
    MASQ_REGION=${MASQ_REGION:-global}

    if [[ "$MASQ_REGION" == "china" ]]; then
        region_default=1
        default_masq="https://www.baidu.com"
        default_sni="www.baidu.com"
    else
        region_default=2
        default_masq="https://www.bing.com"
        default_sni="www.bing.com"
    fi

    if [[ "$AUTO_MODE" == "1" ]]; then
        MASQUERADE="$default_masq"
        SNI="$default_sni"
        return
    fi

    echo -e "${CYAN}[4/6]${NC} 伪装站点区域 ${YELLOW}(须为本机可访问的网站)${NC}:"
    echo -e "  ${GREEN}1${NC}. 国内站点 ${WHITE}(大陆服务器请选这个)${NC}"
    echo -e "  ${GREEN}2${NC}. 海外站点"
    read -rp "$(echo -e "请选择 [${GREEN}${region_default}${NC}]: ")" region_choice
    region_choice=${region_choice:-$region_default}

    if [[ "$region_choice" == "1" ]]; then
        MASQ_REGION="china"
        default_masq="https://www.baidu.com"
        default_sni="www.baidu.com"
        echo -e "${CYAN}请选择国内伪装网站:${NC}"
        echo -e "  ${GREEN}1${NC}. 百度      ${GREEN}2${NC}. 淘宝      ${GREEN}3${NC}. 京东"
        echo -e "  ${GREEN}4${NC}. 哔哩哔哩  ${GREEN}5${NC}. 知乎      ${GREEN}6${NC}. 微博"
        echo -e "  ${GREEN}7${NC}. 网易      ${GREEN}8${NC}. 腾讯      ${GREEN}9${NC}. 阿里云"
        echo -e "  ${GREEN}10${NC}. 华为云   ${GREEN}11${NC}. 抖音     ${GREEN}12${NC}. 自定义"
        read -rp "$(echo -e "请选择 [${GREEN}1${NC}]: ")" site_choice
        case ${site_choice:-1} in
            1)  MASQUERADE="https://www.baidu.com" ;;
            2)  MASQUERADE="https://www.taobao.com" ;;
            3)  MASQUERADE="https://www.jd.com" ;;
            4)  MASQUERADE="https://www.bilibili.com" ;;
            5)  MASQUERADE="https://www.zhihu.com" ;;
            6)  MASQUERADE="https://weibo.com" ;;
            7)  MASQUERADE="https://www.163.com" ;;
            8)  MASQUERADE="https://www.qq.com" ;;
            9)  MASQUERADE="https://www.aliyun.com" ;;
            10) MASQUERADE="https://www.huaweicloud.com" ;;
            11) MASQUERADE="https://www.douyin.com" ;;
            12) read -rp "请输入伪装网站URL(国内可访问): " MASQUERADE ;;
            *)  MASQUERADE="https://www.baidu.com" ;;
        esac
    else
        MASQ_REGION="global"
        default_masq="https://www.bing.com"
        default_sni="www.bing.com"
        if [[ "$LOCATION" == "china" ]]; then
            warning "国内服务器选海外伪装，本机往往访问失败，可能导致伪装无效"
        elif ! probe_url "https://www.google.com" && ! probe_url "https://www.cloudflare.com"; then
            warning "检测到本机较难访问海外站，海外伪装可能无效，建议改选国内站点"
        fi
        echo -e "${CYAN}请选择海外伪装网站:${NC}"
        echo -e "  ${GREEN}1${NC}. Bing       ${GREEN}2${NC}. Google     ${GREEN}3${NC}. YouTube"
        echo -e "  ${GREEN}4${NC}. Cloudflare ${GREEN}5${NC}. Wikipedia  ${GREEN}6${NC}. 自定义"
        read -rp "$(echo -e "请选择 [${GREEN}1${NC}]: ")" site_choice
        case ${site_choice:-1} in
            1) MASQUERADE="https://www.bing.com" ;;
            2) MASQUERADE="https://www.google.com" ;;
            3) MASQUERADE="https://www.youtube.com" ;;
            4) MASQUERADE="https://www.cloudflare.com" ;;
            5) MASQUERADE="https://www.wikipedia.org" ;;
            6) read -rp "请输入伪装网站URL: " MASQUERADE ;;
            *) MASQUERADE="https://www.bing.com" ;;
        esac
    fi

    MASQUERADE=$(normalize_url "$MASQUERADE" "$default_masq")
    if [[ -z "$SNI" ]]; then
        SNI=$(echo "$MASQUERADE" | sed -E 's#^https?://##' | cut -d/ -f1)
        SNI=${SNI:-$default_sni}
    fi
    echo -e "${GREEN}[INFO]${NC} 伪装网站: ${WHITE}$MASQUERADE${NC}"
}

interactive_config() {
    info "[3/5] 开始配置..."
    local default_sni

    MASQ_REGION=${MASQ_REGION:-global}
    if [[ "$MASQ_REGION" == "china" ]]; then
        default_sni="www.baidu.com"
    else
        default_sni="www.bing.com"
    fi

    if [[ "$AUTO_MODE" == "1" ]]; then
        info "自动模式: 使用默认配置"
        SERVER_NAME="Hysteria2"
        PORT="443"
        PASSWORD=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
        choose_masquerade
        generate_selfsigned_cert "$SNI"
        success "自动配置完成 (伪装: $MASQUERADE)"
        return
    fi

    echo
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${PURPLE}                    配置 Hysteria 2 服务端${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo

    read -rp "$(echo -e "${CYAN}[1/6]${NC} 服务名称 [${GREEN}Hysteria2${NC}]: ")" SERVER_NAME
    SERVER_NAME=${SERVER_NAME:-Hysteria2}

    read -rp "$(echo -e "${CYAN}[2/6]${NC} 监听端口 [${GREEN}443${NC}]: ")" PORT
    PORT=${PORT:-443}
    validate_port "$PORT"

    read -rp "$(echo -e "${CYAN}[3/6]${NC} 连接密码 [${GREEN}随机生成${NC}]: ")" PASSWORD
    if [[ -z "$PASSWORD" ]]; then
        PASSWORD=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
    fi
    echo -e "${GREEN}[INFO]${NC} 密码: ${WHITE}$PASSWORD${NC}"
    echo

    SNI=""
    choose_masquerade
    echo

    echo -e "${CYAN}[5/6]${NC} 请选择证书类型:"
    echo -e "  ${GREEN}1${NC}. 自签名证书 (自动生成，无需域名)"
    echo -e "  ${GREEN}2${NC}. 使用已有证书文件"
    read -rp "$(echo -e "请选择 [${GREEN}1${NC}]: ")" CERT_CHOICE
    CERT_CHOICE=${CERT_CHOICE:-1}

    if [[ "$CERT_CHOICE" == "2" ]]; then
        read -rp "证书文件路径: " CERT_PATH
        read -rp "私钥文件路径: " KEY_PATH
        read -rp "$(echo -e "客户端 SNI [${GREEN}${SNI:-$default_sni}${NC}]: ")" SNI_IN
        SNI=${SNI_IN:-${SNI:-$default_sni}}
        if [[ ! -f "$CERT_PATH" || ! -f "$KEY_PATH" ]]; then
            error "证书或私钥文件不存在"
            exit 1
        fi
    else
        echo -e "${CYAN}[6/6]${NC} 自签证书 / 客户端 SNI"
        read -rp "$(echo -e "SNI域名 [${GREEN}${SNI:-$default_sni}${NC}]: ")" SNI_IN
        SNI=${SNI_IN:-${SNI:-$default_sni}}
        generate_selfsigned_cert "$SNI"
    fi
    success "配置完成！"
}

yaml_escape() {
    local s=$1
    s=${s//\\/\\\\}
    s=${s//\"/\\\"}
    printf '"%s"' "$s"
}

generate_config() {
    info "[4/5] 正在生成配置文件..."
    mkdir -p /etc/hysteria

    local fallback="https://www.bing.com"
    [[ "${MASQ_REGION:-}" == "china" ]] && fallback="https://www.baidu.com"
    MASQUERADE=$(normalize_url "$MASQUERADE" "$fallback")
    validate_port "$PORT"

    if [[ ! -f "$CERT_PATH" || ! -f "$KEY_PATH" ]]; then
        error "证书文件缺失: $CERT_PATH / $KEY_PATH"
        exit 1
    fi

    # 🛠️ 优化：去除写死 1gbps 带宽，使用自适应拥塞控制，避免低带宽服务器剧烈丢包
    cat > "$HY2_CONF" << EOF
listen: :${PORT}
tls:
  cert: ${CERT_PATH}
  key: ${KEY_PATH}
auth:
  type: password
  password: $(yaml_escape "$PASSWORD")
masquerade:
  type: proxy
  proxy:
    url: $(yaml_escape "$MASQUERADE")
    rewriteHost: true
quic:
  initStreamReceiveWindow: 8388608
  maxStreamReceiveWindow: 8388608
  initConnReceiveWindow: 20971520
  maxConnReceiveWindow: 20971520
EOF
    success "配置文件已生成: $HY2_CONF"
}

open_firewall() {
    local port="$1"
    info "正在放行 UDP ${port}..."
    if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active --quiet firewalld 2>/dev/null; then
        firewall-cmd --permanent --add-port="${port}/udp" >/dev/null 2>&1 || true
        firewall-cmd --reload >/dev/null 2>&1 || true
    fi
    if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -qi "active"; then
        ufw allow "${port}/udp" >/dev/null 2>&1 || true
    fi
    if command -v iptables >/dev/null 2>&1; then
        iptables -C INPUT -p udp --dport "$port" -j ACCEPT 2>/dev/null \
            || iptables -I INPUT -p udp --dport "$port" -j ACCEPT 2>/dev/null || true
        # 🛠️ 尝试持久化保存 iptables 规则，防止重启失效
        if command -v netfilter-persistent >/dev/null 2>&1; then
            netfilter-persistent save >/dev/null 2>&1 || true
        elif [[ -f /etc/redhat-release ]] && command -v service >/dev/null 2>&1; then
            service iptables save >/dev/null 2>&1 || true
        fi
    fi
    if command -v nft >/dev/null 2>&1 && ! command -v firewall-cmd >/dev/null 2>&1; then
        nft list ruleset 2>/dev/null | grep -q "udp dport ${port}" \
            || nft add rule inet filter input udp dport "$port" accept 2>/dev/null || true
    fi
}

setup_service() {
    info "[5/5] 正在配置系统服务..."

    if ! command -v systemctl >/dev/null 2>&1; then
        error "当前系统无 systemd，无法自动配置服务。请手动运行:"
        echo "  $HY2_BIN server -c $HY2_CONF"
        exit 1
    fi

    systemctl stop hysteria-server.service 2>/dev/null || true
    systemctl reset-failed hysteria-server.service 2>/dev/null || true

    cat > "$HY2_UNIT" << EOF
[Unit]
Description=Hysteria 2 Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Group=root
ExecStart=${HY2_BIN} server -c ${HY2_CONF}
Restart=on-failure
RestartSec=3
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target
EOF

    if command -v restorecon >/dev/null 2>&1; then
        restorecon -v "$HY2_UNIT" 2>/dev/null || true
    fi

    open_firewall "$PORT"
    systemctl daemon-reload
    systemctl enable hysteria-server.service >/dev/null 2>&1 || true
    systemctl start hysteria-server.service
    sleep 2

    if systemctl is-active --quiet hysteria-server.service; then
        success "Hysteria 2 服务已启动并启用开机自启"
    else
        error "服务启动失败，最近日志:"
        journalctl -u hysteria-server.service -n 20 --no-pager 2>/dev/null || true
        exit 1
    fi
}

get_public_ip() {
    local ip
    ip=$(curl -fsS -m 5 https://ipinfo.io/ip 2>/dev/null \
        || curl -fsS -m 5 http://ipinfo.io/ip 2>/dev/null \
        || curl -fsS -m 5 https://api.ipify.org 2>/dev/null \
        || curl -fsS -m 5 https://ifconfig.me 2>/dev/null \
        || true)
    if [[ -z "$ip" ]]; then
        ip=$(hostname -I 2>/dev/null | awk '{print $1}')
    fi
    echo "$ip"
}

urlencode() {
    # 🛠️ 优化：采用 jq/python 原生编码，回退备用快速处理，提高速度与兼容性
    local string="$1"
    if command -v jq >/dev/null 2>&1; then
        jq -rn --arg x "$string" '$x|@uri' 2>/dev/null && return
    elif command -v python3 >/dev/null 2>&1; then
        python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "$string" 2>/dev/null && return
    fi
    
    local LC_ALL=C
    local encoded="" c o
    local -i pos=0 strlen=${#string}
    while (( pos < strlen )); do
        c=${string:pos:1}
        case "$c" in
            [a-zA-Z0-9.~_-]) encoded+="$c" ;;
            *) printf -v o '%%%02X' "'$c"; encoded+="$o" ;;
        esac
        pos+=1
    done
    printf '%s' "$encoded"
}

show_result() {
    local ip hy2_url
    ip=$(get_public_ip)
    echo
    echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║${NC}              ${GREEN}Hysteria 2 安装配置完成！${NC}                      ${CYAN}║${NC}"
    echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
    echo
    echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━ 连接信息 ━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "  ${CYAN}服务名称:${NC}  $SERVER_NAME"
    echo -e "  ${CYAN}服务器IP:${NC}  ${WHITE}$ip${NC}"
    echo -e "  ${CYAN}端口:${NC}      ${WHITE}$PORT${NC}"
    echo -e "  ${CYAN}密码:${NC}      ${WHITE}$PASSWORD${NC}"
    echo -e "  ${CYAN}伪装网站:${NC}  ${WHITE}$MASQUERADE${NC}"
    if [[ -n "$SNI" ]]; then
        echo -e "  ${CYAN}SNI域名:${NC}   ${WHITE}$SNI${NC}"
    fi
    echo
    echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━ 客户端连接链接 ━━━━━━━━━━━━━━━━━━━━${NC}"
    hy2_url="hysteria2://$(urlencode "$PASSWORD")@${ip}:${PORT}?sni=$(urlencode "${SNI:-$ip}")&insecure=1#$(urlencode "$SERVER_NAME")"
    echo -e "  ${WHITE}$hy2_url${NC}"
    echo
    echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━ 管理命令 ━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "  ${CYAN}查看状态:${NC} systemctl status hysteria-server.service"
    echo -e "  ${CYAN}查看日志:${NC} journalctl -u hysteria-server.service -f"
    echo -e "  ${CYAN}重启服务:${NC} systemctl restart hysteria-server.service"
    echo -e "  ${CYAN}停止服务:${NC} systemctl stop hysteria-server.service"
    echo -e "  ${CYAN}配置文件:${NC} $HY2_CONF"
    echo
    echo -e "${GREEN}[SUCCESS]${NC} 安装完成！请使用上方链接配置客户端"
}

main() {
    [[ "$1" == "auto" ]] && AUTO_MODE=1 || AUTO_MODE=0
    banner
    check_root
    detect_os
    detect_location
    install_deps
    install_hysteria
    interactive_config
    generate_config
    setup_service
    show_result
}

main "$@"