#!/bin/bash
#  Tunnel Manager v2.0
# Smart installer with Iran/Kharej detection

SCRIPT_VERSION="v2.0.0"
service_dir="/etc/systemd/system"
config_dir="/usr/local/none-tunnel"
CERT_DIR="${config_dir}/cert_files"
CERT_FILE="$CERT_DIR/cert.crt"
KEY_FILE="$CERT_DIR/cert.key"
BINARY_NAME="nonetunnel-linux-amd64"
BINARY_PATH="/usr/local/bin/${BINARY_NAME}"
DOWNLOAD_URL="https://euro.netarpa.ir/nonetunnel-linux-amd64"
IR_DOWNLOAD_URL="http://ir.netarpa.ir/nonetunnel-linux-amd64"

mkdir -p "$CERT_DIR"

[[ $EUID -ne 0 ]] && { echo "This script must be run as root"; exit 1; }

# ─────────────────────────────────────────
# UI Functions
# ─────────────────────────────────────────

colorize() {
    local color="$1" text="$2" style="${3:-normal}"
    local black="\033[30m" red="\033[31m" green="\033[32m" yellow="\033[33m"
    local blue="\033[34m" magenta="\033[35m" cyan="\033[36m" white="\033[37m"
    local reset="\033[0m" normal="\033[0m" bold="\033[1m" underline="\033[4m"
    local color_code style_code
    case $color in
        black) color_code=$black;; red) color_code=$red;; green) color_code=$green;;
        yellow) color_code=$yellow;; blue) color_code=$blue;; magenta) color_code=$magenta;;
        cyan) color_code=$cyan;; white) color_code=$white;; *) color_code=$reset;;
    esac
    case $style in
        bold) style_code=$bold;; underline) style_code=$underline;; *) style_code=$normal;;
    esac
    echo -e "${style_code}${color_code}${text}${reset}"
}

press_key() {
    echo ""
    echo -ne "\033[90m  [ press any key to continue... ]\033[0m"
    read -r -s -n1
    echo ""
}

prompt_with_default() {
    local prompt="$1" default="$2" var_name="$3" input
    echo -ne "\033[36m  ▸ \033[0m${prompt} \033[90m[${default}]\033[0m: "
    read -r input
    eval "$var_name=\"${input:-$default}\""
}

prompt_boolean() {
    local prompt="$1" default="$2" var_name="$3"
    while true; do
        prompt_with_default "$prompt [true/false]" "$default" "$var_name"
        local value="${!var_name}"
        [[ "$value" == "true" || "$value" == "false" ]] && break
        colorize red "  ✗ Invalid input. Please enter 'true' or 'false'"
    done
}

display_logo() {
    clear
    echo -e "\033[38;5;33m"
    cat << "EOF"
 ███████╗███╗   ███╗██╗  ██╗
 ██╔════╝████╗ ████║██║  ██║
 ███████╗██╔████╔██║███████║
 ╚════██║██║╚██╔╝██║██╔══██║
 ███████║██║ ╚═╝ ██║██║  ██║
 ╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝
EOF
    echo -e "\033[0m"
}

# ─────────────────────────────────────────
# Auto-Detection
# ─────────────────────────────────────────

detect_server_info() {
    SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
    SERVER_IFACE=$(ip route show default 2>/dev/null | awk '{print $5}' | head -1)

    # Try to detect country (for Iran/Kharej auto-suggestion)
    local geo_info
    geo_info=$(curl -sS --max-time 3 "http://ipwhois.app/json/$SERVER_IP" 2>/dev/null)
    SERVER_COUNTRY=$(echo "$geo_info" | jq -r '.country // "Unknown"' 2>/dev/null)
    SERVER_ISP=$(echo "$geo_info" | jq -r '.isp // "Unknown"' 2>/dev/null)
    SERVER_CC=$(echo "$geo_info" | jq -r '.country_code // ""' 2>/dev/null)
}

# ─────────────────────────────────────────
# Validation
# ─────────────────────────────────────────

validate_cidr() {
    local cidr="$1"
    [[ ! "$cidr" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]{1,2})$ ]] && return 1
    local ip mask; IFS='/' read -r ip mask <<< "$cidr"
    local a b c d; IFS='.' read -r a b c d <<< "$ip"
    (( a<0||a>255||b<0||b>255||c<0||c>255||d<0||d>255 )) && return 1
    (( mask < 1 || mask > 32 )) && return 1
    local ip_int=$(( (a<<24)|(b<<16)|(c<<8)|d ))
    local mask_int
    (( mask == 32 )) && mask_int=0xFFFFFFFF || mask_int=$(( (0xFFFFFFFF << (32 - mask)) & 0xFFFFFFFF ))
    local net_int=$(( ip_int & mask_int ))
    local broadcast_int=$(( net_int | (~mask_int & 0xFFFFFFFF) ))
    (( ip_int == net_int )) && return 1
    (( ip_int == broadcast_int )) && return 1
    return 0
}

validate_ip() {
    [[ "$1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
    local a b c d; IFS='.' read -r a b c d <<< "$1"
    (( a<1||a>255||b<0||b>255||c<0||c>255||d<0||d>255 )) && return 1
    return 0
}

# ─────────────────────────────────────────
# Dependencies
# ─────────────────────────────────────────

install_deps() {
    local need_install=()
    command -v jq &>/dev/null || need_install+=(jq)
    command -v curl &>/dev/null || need_install+=(curl)
    if [[ ${#need_install[@]} -gt 0 ]]; then
        colorize yellow "  Installing dependencies: ${need_install[*]}..."
        apt-get update -qq && apt-get install -y "${need_install[@]}" >/dev/null 2>&1
    fi
}

# ─────────────────────────────────────────
# Binary Management
# ─────────────────────────────────────────

download_binary() {
    local from="${1:-}"
    [[ "$ftom" == "menu" ]] && rm -f "${BINARY_PATH}"
    [[ -f "${BINARY_PATH}" ]] && return 0

    mkdir -p "$config_dir"

    # Check local file first (next to script)
    local script_dir
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    if [[ -f "${script_dir}/${BINARY_NAME}" ]]; then
        colorize yellow "  ✔ Local binary found"
        cp "${script_dir}/${BINARY_NAME}" "${BINARY_PATH}"
        chmod u+x "${BINARY_PATH}"
        colorize green "  ✔ Core installed from local file"
        return 0
    fi
    

    # Download from server
    echo "  Downloading Tunnel core..."
    if [[ "$from" == "iran" ]]; then
        if curl -sSL --max-time 30 -o "${BINARY_PATH}" "$IR_DOWNLOAD_URL" 2>/dev/null; then
            chmod u+x "${BINARY_PATH}"
            colorize green "  ✔ Core downloaded and installed"
            return 0
        else
            rm -f "${BINARY_PATH}"
            colorize red "  ✗ Download failed"
            return 1
        fi
        return 0
    fi
    

    if curl -sSL --max-time 30 -o "${BINARY_PATH}" "$DOWNLOAD_URL" 2>/dev/null; then
        chmod u+x "${BINARY_PATH}"
        colorize green "  ✔ Core downloaded and installed"
        return 0
    else
        rm -f "${BINARY_PATH}"
        colorize red "  ✗ Download failed"
        return 1
    fi
}

install_binary_iran() {
    # Iran can't download directly — show instructions
    [[ -f "${BINARY_PATH}" ]] && return 0

    mkdir -p "$config_dir"

    # Check local file
    local script_dir
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    if [[ -f "${script_dir}/${BINARY_NAME}" ]]; then
        cp "${script_dir}/${BINARY_NAME}" "${BINARY_PATH}"
        chmod u+x "${BINARY_PATH}"
        colorize green "  ✔ Core installed from local file"
        return 0
    fi

    echo ""
    colorize yellow "  Iran server has no direct internet access" bold
    echo ""
    echo -e "  \033[90m  Download the binary from Telegram bot:\033[0m"
    echo -e "  \033[36m  Get Tunnel binary file\033[0m"
    echo ""
    echo -e "  \033[90m  Then transfer to server:\033[0m"
    echo -e "  \033[35m  scp ${BINARY_NAME} root@${SERVER_IP}:${config_dir}/\033[0m"
    echo ""
    echo -e "  \033[90m  Or place the binary next to this script and run again.\033[0m"
    echo ""
    press_key
    return 1
}

# ─────────────────────────────────────────
# CONFIG Store
# ─────────────────────────────────────────

declare -A CONFIG
reset_config() { CONFIG=(); }

# ─────────────────────────────────────────
# Smart Prompts
# ─────────────────────────────────────────

VALID_ALGORITHMS=("aes-256-gcm" "chacha20-poly1305" "aes-128-gcm")
is_valid_algorithm() {
    for alg in "${VALID_ALGORITHMS[@]}"; do [[ "$1" == "$alg" ]] && return 0; done; return 1
}

prompt_transport_section() {
    local mode="$1"
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mTransport\033[38;5;240m ───────────────────────────────┐\033[0m"
    echo ""

    local valid_transports=(tcp tcpmux xtcpmux ws wss wsmux wssmux xwsmux anytls tun)
    echo -e "  \033[90m  Available:\033[0m"
    printf "    \033[35m%s\033[0m\n" "${valid_transports[@]}"
    echo ""

    while true; do
        echo -ne "\033[36m  ▸ \033[0mTransport type: "
        read -r CONFIG[transport_type]
        [[ " ${valid_transports[*]} " =~ " ${CONFIG[transport_type]} " ]] && break
        colorize red "  ✗ Invalid transport type."
    done

    if [[ "${CONFIG[transport_type]}" == "tun" ]]; then
        echo ""
        local encapsulations=(tcp ipx)
        echo -e "  \033[90m  Encapsulation:\033[0m"
        printf "    \033[35m%s\033[0m\n" "${encapsulations[@]}"
        echo ""
        while true; do
            echo -ne "\033[36m  ▸ \033[0mEncapsulation type: "
            read -r CONFIG[tun_encapsulation]
            [[ " ${encapsulations[*]} " =~ " ${CONFIG[tun_encapsulation]} " ]] && break
            colorize red "  ✗ Invalid encapsulation."
        done
    fi

    echo ""
    local is_ipx="false"
    [[ "${CONFIG[tun_encapsulation]}" == "ipx" ]] && is_ipx="true"

    [[ "$is_ipx" != "true" ]] && prompt_boolean "TCP No-Delay" "true" CONFIG[nodelay]

    if [[ "$mode" == "server" ]]; then
        [[ "${CONFIG[transport_type]}" == "tcp" ]] && prompt_boolean "Accept UDP over TCP" "false" CONFIG[accept_udp]
        if [[ ! "${CONFIG[transport_type]}" =~ ^(tun|ws)$ ]] && [[ "$is_ipx" != "true" ]]; then
            prompt_boolean "Proxy Protocol" "false" CONFIG[proxy_protocol]
        fi
    else
        [[ "${CONFIG[transport_type]}" != "tun" ]] && prompt_with_default "Connection Pool Size" "8" CONFIG[connection_pool]
    fi

    CONFIG[heartbeat_interval]="10"
    CONFIG[heartbeat_timeout]="25"
    [[ "$is_ipx" != "true" ]] && CONFIG[keepalive_period]="40"
    echo ""
}

prompt_connection_section() {
    local mode="$1"
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mConnection\033[38;5;240m ──────────────────────────────┐\033[0m"
    echo ""

    if [[ "$mode" == "server" ]]; then
        prompt_with_default "Bind Address" ":8443" CONFIG[bind_addr]
        [[ -n "${CONFIG[bind_addr]}" && "${CONFIG[bind_addr]}" != *:* ]] && CONFIG[bind_addr]=":${CONFIG[bind_addr]}"
    else
        while true; do
            echo -ne "\033[36m  ▸ \033[0mIRAN Server Address \033[90m[IP:Port / Domain:Port]\033[0m: "
            read -r CONFIG[remote_addr]
            [[ -z "${CONFIG[remote_addr]}" ]] && { colorize red "  ✗ Cannot be empty."; continue; }
            [[ "${CONFIG[remote_addr]}" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}$ || \
               "${CONFIG[remote_addr]}" =~ ^[a-zA-Z0-9.-]+:[0-9]{1,5}$ ]] && break
            colorize red "  ✗ Invalid format. Use IP:Port or Domain:Port."
        done

        [[ "${CONFIG[transport_type]}" =~ ^(ws|wss|wsmux|wssmux|xwsmux)$ ]] && {
            echo -ne "\033[36m  ▸ \033[0mEdge IP/Domain \033[90m[optional]\033[0m: "
            read -r CONFIG[edge_ip]
        }
        CONFIG[dial_timeout]="10"
        CONFIG[retry_interval]="3"
    fi
    echo ""
}

prompt_security_section() {
    local is_ipx="$1"
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mSecurity\033[38;5;240m ────────────────────────────────┐\033[0m"
    echo ""

    if [[ "$is_ipx" == "true" ]]; then
        prompt_boolean "Enable Encryption" "true" CONFIG[enable_encryption]
        if [[ "${CONFIG[enable_encryption]}" == "true" ]]; then
            echo ""
            echo -e "  \033[90m  Available: \033[35maes-256-gcm  chacha20-poly1305  aes-128-gcm\033[0m"
            while true; do
                prompt_with_default "Algorithm" "aes-256-gcm" CONFIG[algorithm]
                is_valid_algorithm "${CONFIG[algorithm]}" && break
                colorize red "  ✗ Invalid algorithm."
                echo ""
            done
            prompt_with_default "PSK Key (base64)" "pN9m6m0tH3nE3V8xKZ6Lq5yYcW2K1S7QG9u4cF0A8M4=" CONFIG[psk]
            prompt_with_default "KDF Iterations" "100000" CONFIG[kdf_iterations]
        fi
    else
        prompt_with_default "Security Token" "your_token" CONFIG[token]
        CONFIG[enable_encryption]="false"
    fi
    echo ""
}

prompt_tun_section() {
    local transport="$1" mode="$2" is_ipx="$3"
    [[ "$transport" != "tun" ]] && return

    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mTUN Interface\033[38;5;240m ───────────────────────────┐\033[0m"
    echo ""
    prompt_with_default "Device Name" "NONET" CONFIG[tun_name]

    local default_local default_remote
    if [[ "$mode" == "server" ]]; then
        default_local="10.10.10.1/24"; default_remote="10.10.10.2/24"
    else
        default_local="10.10.10.2/24"; default_remote="10.10.10.1/24"
    fi

    while true; do
        prompt_with_default "Local Address (CIDR)" "$default_local" CONFIG[tun_local_addr]
        validate_cidr "${CONFIG[tun_local_addr]}" && break
        colorize red "  ✗ Invalid CIDR."
    done
    while true; do
        prompt_with_default "Remote Address (CIDR)" "$default_remote" CONFIG[tun_remote_addr]
        validate_cidr "${CONFIG[tun_remote_addr]}" && break
        colorize red "  ✗ Invalid CIDR."
    done

    prompt_with_default "Health Check Port" "1234" CONFIG[tun_health_port]
    [[ "$is_ipx" == "true" ]] && prompt_with_default "MTU" "1320" CONFIG[tun_mtu] || prompt_with_default "MTU" "1500" CONFIG[tun_mtu]
    echo ""
}

prompt_ipx_section() {
    local is_ipx="$1" mode="$2"
    [[ "$is_ipx" != "true" ]] && return

    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mIPX\033[38;5;240m ─────────────────────────────────────┐\033[0m"
    echo ""
    CONFIG[ipx_mode]="$mode"

    local AVAILABLE_PROFILES=("icmp" "ipip" "udp" "tcp" "gre" "bip")
    echo -e "  \033[90m  Profiles: \033[35m${AVAILABLE_PROFILES[*]}\033[0m"
    echo ""

    while true; do
        prompt_with_default "Profile" "tcp" CONFIG[ipx_profile]
        CONFIG[ipx_profile]="${CONFIG[ipx_profile],,}"
        for p in "${AVAILABLE_PROFILES[@]}"; do
            [[ "${CONFIG[ipx_profile]}" == "$p" ]] && break 2
        done
        colorize red "  ✗ Invalid profile."
        echo ""
    done

    # Auto-detect listen IP
    prompt_with_default "Listen IP" "${SERVER_IP}" CONFIG[ipx_listen_ip]

    while true; do
        prompt_with_default "Destination IP" "" CONFIG[ipx_dst_ip]
        [[ -n "${CONFIG[ipx_dst_ip]}" ]] && break
        colorize red "  ✗ Cannot be empty."
    done

    echo ""
    prompt_boolean "Enable IP Spoofing" "false" CONFIG[ipx_enable_spoof]
    if [[ "${CONFIG[ipx_enable_spoof]}" == "true" ]]; then
        echo ""
        while true; do
            prompt_with_default "Spoof Source IP" "" CONFIG[ipx_spoof_src_ip]
            [[ -n "${CONFIG[ipx_spoof_src_ip]}" ]] && break
            colorize red "  ✗ Cannot be empty."
        done
        while true; do
            prompt_with_default "Spoof Destination IP" "" CONFIG[ipx_spoof_dst_ip]
            [[ -n "${CONFIG[ipx_spoof_dst_ip]}" ]] && break
            colorize red "  ✗ Cannot be empty."
        done
    fi

    # Auto-detect interface
    prompt_with_default "Network Interface" "${SERVER_IFACE}" CONFIG[ipx_interface]

    if [[ "${CONFIG[ipx_profile]}" == "icmp" ]]; then
        prompt_with_default "ICMP Type" "0" CONFIG[ipx_icmp_type]
        prompt_with_default "ICMP Code" "0" CONFIG[ipx_icmp_code]
    fi
    echo ""
}

prompt_mux_section() {
    local transport="$1"
    [[ ! "$transport" =~ mux$ ]] && return
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mMux\033[38;5;240m ─────────────────────────────────────┐\033[0m"
    echo ""
    prompt_with_default "Mux Version [1/2]" "2" CONFIG[mux_version]
    prompt_with_default "Mux Concurrency" "8" CONFIG[mux_concurrency]
    CONFIG[mux_framesize]="32768"
    CONFIG[mux_recievebuffer]="4194304"
    CONFIG[mux_streambuffer]="2097152"
    echo ""
}

prompt_tls_section() {
    local mode="$1" transport="$2"
    [[ ! "$transport" =~ ^(anytls|wss|wssmux)$ ]] && return
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mTLS\033[38;5;240m ─────────────────────────────────────┐\033[0m"
    echo ""
    [[ "$transport" == "anytls" ]] && prompt_with_default "SNI Hostname" "www.digikala.com" CONFIG[tls_sni]
    [[ "$mode" == "client" ]] && { echo; return; }
    if [[ ! -f "$CERT_FILE" || ! -f "$KEY_FILE" ]]; then
        colorize yellow "  ⚠ Generating self-signed certificate..."
        openssl req -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
            -nodes -x509 -days 365 -sha256 \
            -keyout "$KEY_FILE" -out "$CERT_FILE" \
            -subj "/CN=nonet.local" 2>/dev/null
        colorize green "  ✔ Certificate generated"
        echo ""
    fi
    prompt_with_default "Certificate Path" "$CERT_FILE" CONFIG[tls_cert]
    prompt_with_default "Private Key Path" "$KEY_FILE" CONFIG[tls_key]
    echo ""
}

prompt_tuning_section() {
    local is_ipx="$1" is_tun="$2"
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mPerformance Tuning\033[38;5;240m ──────────────────────┐\033[0m"
    echo ""
    prompt_boolean "Auto Tuning" "true" CONFIG[auto_tuning]
    echo ""
    echo -e "  \033[90m  Profiles: \033[35mbalanced  fast  latency  resource\033[0m"
    prompt_with_default "Tuning Profile" "balanced" CONFIG[tuning_profile]
    prompt_with_default "Workers (0=auto)" "0" CONFIG[workers]

    [[ "$is_tun" != "true" ]] && prompt_with_default "Channel Size" "4096" CONFIG[channel_size] || CONFIG[channel_size]="10_000"

    if [[ "$is_ipx" == "true" ]]; then
        prompt_with_default "Batch Size" "2048" CONFIG[batch_size]
        prompt_with_default "SO_SNDBUF (0=auto)" "0" CONFIG[so_sndbuf]
    else
        prompt_with_default "TCP MSS (0=auto)" "0" CONFIG[tcp_mss]
        prompt_with_default "SO_RCVBUF (0=auto)" "0" CONFIG[so_rcvbuf]
        prompt_with_default "SO_SNDBUF (0=auto)" "0" CONFIG[so_sndbuf]
    fi

    if [[ "$is_tun" != "true" && "$is_ipx" != "true" ]]; then
        echo ""
        echo -e "  \033[90m  Buffer: \033[35mextreme_low_cpu  ultra_low_cpu  low_cpu  balanced  low_memory\033[0m"
        prompt_with_default "Buffer Profile" "balanced" CONFIG[buffer_profile]
        prompt_with_default "Read Timeout" "120" CONFIG[read_timeout]
    fi
    echo ""
}

prompt_logging_section() {
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mLogging\033[38;5;240m ─────────────────────────────────┐\033[0m"
    echo ""
    echo -e "  \033[90m  Levels: \033[35mpanic  fatal  error  warn  info  debug  trace\033[0m"
    prompt_with_default "Log Level" "info" CONFIG[log_level]
    echo ""
}

prompt_license_section() {
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mLicense\033[38;5;240m ─────────────────────────────────┐\033[0m"
    echo ""
    echo -e "  \033[90m  Get your license key from the Telegram bot\033[0m"
    echo -e "  \033[90m  Server IP will be auto-registered after activation\033[0m"
    echo ""
    prompt_with_default "License Key" "" CONFIG[license_key]
    [[ -z "${CONFIG[license_key]}" ]] && colorize yellow "  Warning: tunnel won't work without a license key!"
    echo ""
}

prompt_accept_udp_section() {
    [[ "$1" != "true" ]] && return
    CONFIG[ring_size]="64"
    CONFIG[frame_size]="2048"
    CONFIG[peer_idle_timeout_s]="120"
    CONFIG[write_timeout_ms]="3"
}

prompt_ports_section() {
    local mode="$1" is_tun="$2"
    [[ "$mode" != "server" ]] && return
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mPort Mapping\033[38;5;240m ────────────────────────────┐\033[0m"
    echo ""
    if [[ "$is_tun" != "true" ]]; then
        echo -e "  \033[90m  Formats:\033[0m"
        echo -e "    \033[90m443\033[0m           → forward to same port"
        echo -e "    \033[90m443=5000\033[0m      → forward to 5000"
        echo -e "    \033[90m443-600\033[0m       → port range"
        echo -e "    \033[90m443-600:5201\033[0m  → range to single port"
    else
        echo -e "  \033[90m  Forwarder: \033[35mnonet\033[90m (TCP) or \033[35miptables\033[90m (TCP+UDP)\033[0m"
        prompt_with_default "Forwarder" "nonet" CONFIG[forwarder]
        echo ""
        echo -e "  \033[90m  Formats: \033[35m443\033[90m or \033[35m443=5000\033[0m"
    fi
    echo ""
    echo -ne "\033[36m  ▸ \033[0mPort mappings \033[90m[comma-separated]\033[0m: "
    read -r CONFIG[ports_mapping]
    echo ""
}

# ─────────────────────────────────────────
# TOML Generator
# ─────────────────────────────────────────

generate_toml_config() {
    local mode="$1" output_file="$2" is_tun="$3" is_ipx="$4"

    {
        echo "#  Tunnel Config — Generated by dr.smh ${SCRIPT_VERSION}"
        echo "# $(date '+%Y-%m-%d %H:%M:%S')"
        echo ""

        if [[ "$mode" == "server" && "$is_ipx" == "false" ]]; then
            echo "[listener]"
            echo "bind_addr = \"${CONFIG[bind_addr]}\""
            echo ""
        elif [[ "$is_ipx" == "false" ]]; then
            echo "[dialer]"
            echo "remote_addr = \"${CONFIG[remote_addr]}\""
            [[ -n "${CONFIG[edge_ip]}" ]] && echo "edge_ip = \"${CONFIG[edge_ip]}\""
            echo "dial_timeout = ${CONFIG[dial_timeout]}"
            echo "retry_interval = ${CONFIG[retry_interval]}"
            echo ""
        fi

        echo "[transport]"
        echo "type = \"${CONFIG[transport_type]}\""
        [[ -n "${CONFIG[nodelay]}" ]] && echo "nodelay = ${CONFIG[nodelay]}"
        [[ -n "${CONFIG[keepalive_period]}" ]] && echo "keepalive_period = ${CONFIG[keepalive_period]}"
        if [[ "$mode" == "server" ]]; then
            [[ -n "${CONFIG[accept_udp]}" ]] && echo "accept_udp = ${CONFIG[accept_udp]}"
            [[ -n "${CONFIG[proxy_protocol]}" ]] && echo "proxy_protocol = ${CONFIG[proxy_protocol]}"
        else
            [[ -n "${CONFIG[connection_pool]}" && "${CONFIG[connection_pool]}" != "0" ]] && echo "connection_pool = ${CONFIG[connection_pool]}"
        fi
        [[ -n "${CONFIG[heartbeat_interval]}" ]] && echo "heartbeat_interval = ${CONFIG[heartbeat_interval]}"
        [[ -n "${CONFIG[heartbeat_timeout]}" ]] && echo "heartbeat_timeout = ${CONFIG[heartbeat_timeout]}"
        echo ""

        if [[ "$is_tun" == "true" ]]; then
            echo "[tun]"
            echo "encapsulation = \"${CONFIG[tun_encapsulation]}\""
            echo "name = \"${CONFIG[tun_name]}\""
            echo "local_addr = \"${CONFIG[tun_local_addr]}\""
            echo "remote_addr = \"${CONFIG[tun_remote_addr]}\""
            echo "health_port = ${CONFIG[tun_health_port]}"
            echo "mtu = ${CONFIG[tun_mtu]}"
            echo ""
        fi

        if [[ "$is_ipx" == "true" ]]; then
            echo "[ipx]"
            echo "mode = \"${CONFIG[ipx_mode]}\""
            echo "profile = \"${CONFIG[ipx_profile]}\""
            echo "listen_ip = \"${CONFIG[ipx_listen_ip]}\""
            echo "dst_ip = \"${CONFIG[ipx_dst_ip]}\""
            [[ "${CONFIG[ipx_enable_spoof]}" == "true" ]] && echo "spoof_src_ip = \"${CONFIG[ipx_spoof_src_ip]}\""
            [[ "${CONFIG[ipx_enable_spoof]}" == "true" ]] && echo "spoof_dst_ip = \"${CONFIG[ipx_spoof_dst_ip]}\""
            echo "interface = \"${CONFIG[ipx_interface]}\""
            [[ -n "${CONFIG[ipx_icmp_type]}" ]] && echo "icmp_type = ${CONFIG[ipx_icmp_type]}"
            [[ -n "${CONFIG[ipx_icmp_code]}" ]] && echo "icmp_code = ${CONFIG[ipx_icmp_code]}"
            echo ""
        fi

        if [[ "${CONFIG[transport_type]}" =~ mux$ ]]; then
            echo "[mux]"
            echo "mux_version = ${CONFIG[mux_version]}"
            echo "mux_framesize = ${CONFIG[mux_framesize]}"
            echo "mux_recievebuffer = ${CONFIG[mux_recievebuffer]}"
            echo "mux_streambuffer = ${CONFIG[mux_streambuffer]}"
            [[ -n "${CONFIG[mux_concurrency]}" ]] && echo "mux_concurrency = ${CONFIG[mux_concurrency]}"
            echo ""
        fi

        echo "[security]"
        if [[ "$is_ipx" == "true" ]]; then
            echo "enable_encryption = ${CONFIG[enable_encryption]}"
            if [[ "${CONFIG[enable_encryption]}" == "true" ]]; then
                echo "algorithm = \"${CONFIG[algorithm]}\""
                echo "psk = \"${CONFIG[psk]}\""
                echo "kdf_iterations = ${CONFIG[kdf_iterations]}"
            fi
        else
            echo "token = \"${CONFIG[token]}\""
        fi
        echo ""

        if [[ -n "${CONFIG[tls_sni]}" || -n "${CONFIG[tls_cert]}" ]]; then
            echo "[tls]"
            [[ -n "${CONFIG[tls_sni]}" ]] && echo "sni = \"${CONFIG[tls_sni]}\""
            [[ -n "${CONFIG[tls_cert]}" ]] && echo "tls_cert = \"${CONFIG[tls_cert]}\""
            [[ -n "${CONFIG[tls_key]}" ]] && echo "tls_key = \"${CONFIG[tls_key]}\""
            echo ""
        fi

        echo "[tuning]"
        [[ -n "${CONFIG[auto_tuning]}" ]] && echo "auto_tuning = ${CONFIG[auto_tuning]}"
        [[ -n "${CONFIG[tuning_profile]}" ]] && echo "tuning_profile = \"${CONFIG[tuning_profile]}\""
        [[ -n "${CONFIG[workers]}" ]] && echo "workers = ${CONFIG[workers]}"
        [[ -n "${CONFIG[channel_size]}" ]] && echo "channel_size = ${CONFIG[channel_size]}"
        [[ -n "${CONFIG[tcp_mss]}" ]] && echo "tcp_mss = ${CONFIG[tcp_mss]}"
        [[ -n "${CONFIG[so_rcvbuf]}" ]] && echo "so_rcvbuf = ${CONFIG[so_rcvbuf]}"
        [[ -n "${CONFIG[so_sndbuf]}" ]] && echo "so_sndbuf = ${CONFIG[so_sndbuf]}"
        [[ -n "${CONFIG[buffer_profile]}" ]] && echo "buffer_profile = \"${CONFIG[buffer_profile]}\""
        [[ -n "${CONFIG[batch_size]}" ]] && echo "batch_size = ${CONFIG[batch_size]}"
        [[ -n "${CONFIG[read_timeout]}" ]] && echo "read_timeout = ${CONFIG[read_timeout]}"
        echo ""

        if [[ "${CONFIG[accept_udp]}" == "true" ]]; then
            echo "[accept_udp]"
            echo "ring_size = ${CONFIG[ring_size]}"
            echo "frame_size = ${CONFIG[frame_size]}"
            echo "peer_idle_timeout_s = ${CONFIG[peer_idle_timeout_s]}"
            echo "write_timeout_ms = ${CONFIG[write_timeout_ms]}"
            echo ""
        fi

        echo "[logging]"
        echo "log_level = \"${CONFIG[log_level]}\""
        echo ""

        # License — only for client (abroad)
        if [[ "$mode" == "client" && -n "${CONFIG[license_key]}" ]]; then
            echo "[license]"
            echo "key = \"${CONFIG[license_key]}\""
            echo ""
        fi

        if [[ "$mode" == "server" ]]; then
            echo "[ports]"
            [[ -n "${CONFIG[forwarder]}" ]] && echo "forwarder = \"${CONFIG[forwarder]}\""
            echo "mapping = ["
            IFS=',' read -r -a ports <<< "${CONFIG[ports_mapping]}"
            for port in "${ports[@]}"; do
                [[ -n "$port" ]] && echo "    \"${port// /}\","
            done
            echo "]"
        fi
    } > "$output_file"
}

# ─────────────────────────────────────────
# Service Management
# ─────────────────────────────────────────

create_systemd_service() {
    local type="$1" port="$2" config_file="$3" mode="$4"
    local service_file="${service_dir}/none-${type}${port}.service"
    local desc_type
    desc_type="$(tr '[:lower:]' '[:upper:]' <<< "${type:0:1}")${type:1}"

    # Client (abroad) uses RestartPreventExitStatus=10 for license disconnect
    local restart_line="Restart=on-failure"
    local extra_line=""
    if [[ "$mode" == "client" ]]; then
        extra_line="RestartPreventExitStatus=10"
    fi

    cat > "$service_file" <<EOF
[Unit]
Description=NONE Tunnel $desc_type Port $port
After=network.target

[Service]
Type=simple
User=root
ExecStart=${BINARY_PATH} -c $config_file
${restart_line}
RestartSec=3
${extra_line}
LimitNOFILE=1048576
TasksMax=infinity
LimitMEMLOCK=infinity
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable --now "none-${type}${port}.service" >/dev/null 2>&1
    colorize green "  ✔ Service none-${type}${port} created and started" bold
}

# ─────────────────────────────────────────
# Configure Tunnel (smart flow)
# ─────────────────────────────────────────

configure_tunnel_smart() {
    local mode="$1"
    local mode_name
    [[ "$mode" == "server" ]] && mode_name="🇮🇷 IRAN (Server)" || mode_name="🌍 KHAREJ (Client)"

    # Check binary
    if [[ ! -f "${BINARY_PATH}" ]]; then
        if [[ "$mode" == "client" ]]; then
            download_binary || { press_key; return 1; }
        else
            install_binary_iran || return 1
        fi
    fi

    clear
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mConfiguring ${mode_name}\033[38;5;240m ──────────────────────┐\033[0m"
    echo ""
    reset_config

    prompt_transport_section "$mode"

    local is_tun="false" is_ipx="false"
    [[ "${CONFIG[transport_type]}" == "tun" ]] && is_tun="true"
    [[ "${CONFIG[tun_encapsulation]}" == "ipx" ]] && is_ipx="true"

    prompt_tun_section "${CONFIG[transport_type]}" "$mode" "$is_ipx"
    prompt_ipx_section "$is_ipx" "$mode"
    [[ "$is_ipx" != "true" ]] && prompt_connection_section "$mode"
    prompt_security_section "$is_ipx"
    prompt_accept_udp_section "${CONFIG[accept_udp]}"
    prompt_mux_section "${CONFIG[transport_type]}"
    prompt_tls_section "$mode" "${CONFIG[transport_type]}"
    prompt_tuning_section "$is_ipx" "$is_tun"
    prompt_logging_section

    # License — only for client (abroad)
    #[[ "$mode" == "client" ]] && prompt_license_section

    prompt_ports_section "$mode" "$is_tun"

    # Determine port for naming
    local tunnel_port
    if [[ "$mode" == "server" ]]; then
        tunnel_port=$(echo "${CONFIG[bind_addr]}" | grep -oP ':\K[0-9]+$')
    else
        tunnel_port=$(echo "${CONFIG[remote_addr]}" | grep -oP ':\K[0-9]+$')
    fi
    [[ -z "$tunnel_port" ]] && tunnel_port="${CONFIG[tun_health_port]}"

    local config_file service_type
    if [[ "$mode" == "server" ]]; then
        config_file="${config_dir}/iran${tunnel_port}.toml"
        service_type="iran"
    else
        config_file="${config_dir}/kharej${tunnel_port}.toml"
        service_type="kharej"
    fi

    generate_toml_config "$mode" "$config_file" "$is_tun" "$is_ipx"
    create_systemd_service "$service_type" "$tunnel_port" "$config_file" "$mode"

    echo ""
    colorize green "  ✔ Configuration completed!" bold
    if [[ "$mode" == "client" ]]; then
        echo ""
        echo -e "  \033[90m  Server IP will be auto-registered in license after activation\033[0m"
    fi
    echo ""
    press_key
}

# ─────────────────────────────────────────
# Tunnel Status
# ─────────────────────────────────────────

check_tunnel_status() {
    if ! ls "$config_dir"/*.toml &>/dev/null; then
        colorize red "  ✗ No tunnels found." bold
        press_key; return 1
    fi
    clear
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mTunnel Status\033[38;5;240m ───────────────────────────┐\033[0m"
    echo ""
    for config_path in "$config_dir"/{iran,kharej}*.toml; do
        [ -f "$config_path" ] || continue
        local config_name service_name
        config_name=$(basename "${config_path%.toml}")
        service_name="none-${config_name}.service"
        if [[ "$config_name" =~ ^(iran|kharej)([0-9]+)$ ]]; then
            local loc="${BASH_REMATCH[1]}" port="${BASH_REMATCH[2]}"
            local label; [[ "$loc" == "iran" ]] && label="Iran Server  " || label="Kharej Client"
            if systemctl is-active --quiet "$service_name"; then
                echo -e "  \033[32m●\033[0m  ${label} \033[38;5;240m·\033[0m port \033[33m${port}\033[0m  \033[32m[running]\033[0m"
            else
                echo -e "  \033[31m○\033[0m  ${label} \033[38;5;240m·\033[0m port \033[33m${port}\033[0m  \033[31m[stopped]\033[0m"
            fi
        fi
    done
    echo ""
    press_key
}

# ─────────────────────────────────────────
# Tunnel Management
# ─────────────────────────────────────────

tunnel_management() {
    if ! ls "$config_dir"/*.toml &>/dev/null; then
        colorize red "  ✗ No tunnels found." bold
        press_key; return 1
    fi
    clear
    echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33mTunnel Management\033[38;5;240m ───────────────────────┐\033[0m"
    echo ""
    local index=1; declare -a configs
    for config_path in "$config_dir"/{iran,kharej}*.toml; do
        [ -f "$config_path" ] || continue
        local config_name; config_name=$(basename "$config_path")
        if [[ "$config_name" =~ ^(iran|kharej)([0-9]+)\.toml$ ]]; then
            local loc="${BASH_REMATCH[1]}" port="${BASH_REMATCH[2]}"
            configs+=("$config_path")
            local label; [[ "$loc" == "iran" ]] && label="Iran Server  " || label="Kharej Client"
            echo -e "  \033[38;5;240m[\033[32m${index}\033[38;5;240m]\033[0m  ${label} \033[38;5;240m·\033[0m port \033[33m${port}\033[0m"
            ((index++))
        fi
    done
    echo ""
    echo -ne "  \033[38;5;33m❯\033[0m  Select tunnel \033[90m[0 to go back]\033[0m: "
    read -r choice
    [[ "$choice" == "0" ]] && return
    while ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#configs[@]} )); do
        colorize red "  ✗ Invalid."
        echo -ne "  \033[38;5;33m❯\033[0m  Select: "
        read -r choice
        [[ "$choice" == "0" ]] && return
    done

    local selected="${configs[$((choice - 1))]}"
    local cname; cname=$(basename "${selected%.toml}")
    local sname="none-${cname}.service"

    clear; echo ""
    echo -e "  \033[38;5;240m┌── \033[38;5;33m${cname}\033[38;5;240m ──────────────────────────────┐\033[0m"
    echo ""
    echo -e "  \033[31m  [1]\033[0m  Remove tunnel"
    echo -e "  \033[33m  [2]\033[0m  Restart tunnel"
    echo -e "  \033[36m  [3]\033[0m  View logs"
    echo -e "  \033[90m  [4]\033[0m  Service status"
    echo -e "  \033[35m  [5]\033[0m  Edit config"
    echo ""
    echo -ne "  \033[38;5;33m❯\033[0m  Action \033[90m[0 back]\033[0m: "
    read -r action
    case $action in
        1)
            [ -f "$selected" ] && rm -f "$selected"
            if [[ -f "${service_dir}/${sname}" ]]; then
                systemctl is-active --quiet "$sname" && systemctl disable --now "$sname" >/dev/null 2>&1
                rm -f "${service_dir}/${sname}"
            fi
            systemctl daemon-reload
            colorize green "  ✔ Tunnel removed."
            press_key ;;
        2)
            systemctl restart "$sname" 2>/dev/null && colorize green "  ✔ Restarted." || colorize red "  ✗ Failed."
            press_key ;;
        3) clear; journalctl -eu "$sname" -f -o cat ;;
        4) clear; systemctl status "$sname"; press_key ;;
        5) ${EDITOR:-nano} "$selected"; press_key ;;
        0) return ;;
        *) colorize red "  ✗ Invalid." && sleep 1 ;;
    esac
}

# ─────────────────────────────────────────
# Core Management
# ─────────────────────────────────────────

remove_core() {
    if find "$config_dir" -type f -name "*.toml" 2>/dev/null | grep -q .; then
        colorize red "  ✗ Remove all tunnels first."
        sleep 3; return 1
    fi
    echo ""
    echo -ne "  \033[31m▸\033[0m Remove Tunnel Core? \033[90m[y/N]\033[0m: "
    read -r confirm
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
        [[ -d "$config_dir" ]] && rm -rf "$config_dir"
        colorize green "  ✔  Tunnel Core removed."
    fi
    press_key
}

update_core() {
    if [[ "$SERVER_MODE" == "iran" ]]; then
        colorize yellow "  Iran server — download new binary from Telegram bot:" bold
        echo ""
        echo -e "  \033[35m  ${BINARY_PATH}\033[0m"
        press_key
    else
        download_binary "menu"
        [[ -f "${BINARY_PATH}" ]] && colorize cyan "  ⚠ Restart tunnels to use new core" bold
        sleep 2
    fi
}

# ─────────────────────────────────────────
# Config Backup Check
# ─────────────────────────────────────────

check_config_backup() {
    local missing=()
    for config in "${config_dir}"/iran*.toml "${config_dir}"/kharej*.toml; do
        [ -e "$config" ] || continue
        local fname; fname=$(basename "$config")
        if [[ "$fname" =~ ^(iran|kharej)([0-9]+)\.toml$ ]]; then
            local loc="${BASH_REMATCH[1]}" tp="${BASH_REMATCH[2]}"
            local sf="${service_dir}/none-${loc}${tp}.service"
            [[ ! -f "$sf" ]] && missing+=("${loc}:${tp}")
        fi
    done
    [[ ${#missing[@]} -eq 0 ]] && return 0
    echo ""
    colorize red "  Missing service files detected:" bold
    for entry in "${missing[@]}"; do
        local loc="${entry%%:*}" tp="${entry##*:}"
        echo "    - none-${loc}${tp}.service"
    done
    echo ""
    read -r -p "  Recreate? (y/n): " confirm
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
        for entry in "${missing[@]}"; do
            local loc="${entry%%:*}" tp="${entry##*:}"
            local cf="${config_dir}/${loc}${tp}.toml"
            local mode; [[ "$loc" == "iran" ]] && mode="server" || mode="client"
            create_systemd_service "$loc" "$tp" "$cf" "$mode"
        done
    fi
    sleep 2
}

# ─────────────────────────────────────────
# Main Menu
# ─────────────────────────────────────────

SERVER_MODE=""  # "iran" or "abroad"

select_server_mode() {
    display_logo
    echo -e "  \033[38;5;240m┌── \033[38;5;33mServer Type\033[38;5;240m ─────────────────────────────┐\033[0m"
    echo ""

    # Auto-suggest based on country
    local suggestion=""
    if [[ "$SERVER_CC" == "IR" ]]; then
        suggestion=" \033[90m(detected: Iran)\033[0m"
    elif [[ -n "$SERVER_CC" && "$SERVER_CC" != "IR" ]]; then
        suggestion=" \033[90m(detected: ${SERVER_COUNTRY})\033[0m"
    fi

    echo -e "  \033[32m  [1]\033[0m  Iran Server${suggestion}"
    echo -e "  \033[35m  [2]\033[0m  Kharej Server"
    echo ""
    echo -e "  \033[38;5;240m└────────────────────────────────────────────┘\033[0m"
        echo ""
    echo -ne "  \033[38;5;33m❯\033[0m  "

    read -r choice
    case $choice in
        1) SERVER_MODE="iran" ;;
        2) SERVER_MODE="abroad" ;;
        *) colorize red "  ✗ Invalid."; sleep 1; select_server_mode ;;
    esac
}

display_menu() {
    display_logo

    local core_status core_color
    if [[ -f "${BINARY_PATH}" ]]; then
        core_status="Installed"; core_color="\033[32m"
    else
        core_status="Not Installed"; core_color="\033[31m"
    fi

    local mode_label
    [[ "$SERVER_MODE" == "iran" ]] && mode_label="🇮🇷 Iran" || mode_label="🌍 Kharej"

    echo -e "\033[38;5;240m  ┌─────────────────────────────────────────────────┐\033[0m"
    echo -e "\033[38;5;240m  │\033[0m  \033[38;5;33m Mode\033[0m       \033[38;5;240m·\033[0m  \033[97m${mode_label}\033[0m"
    echo -e "\033[38;5;240m  │\033[0m  \033[38;5;33m IP\033[0m         \033[38;5;240m·\033[0m  \033[97m${SERVER_IP:-N/A}\033[0m"
    echo -e "\033[38;5;240m  │\033[0m  \033[38;5;33m Location\033[0m   \033[38;5;240m·\033[0m  \033[97m${SERVER_COUNTRY:-Unknown}\033[0m"
    echo -e "\033[38;5;240m  │\033[0m  \033[38;5;33m ISP\033[0m        \033[38;5;240m·\033[0m  \033[97m${SERVER_ISP:-Unknown}\033[0m"
    echo -e "\033[38;5;240m  │\033[0m  \033[38;5;33m Core\033[0m       \033[38;5;240m·\033[0m  ${core_color}${core_status}\033[0m"
    echo -e "\033[38;5;240m  ├─────────────────────────────────────────────────┤\033[0m"
    echo -e "\033[38;5;240m  │\033[0m                                                   \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[32m 1 \033[38;5;240m·\033[0m  New Tunnel                               \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[33m 2 \033[38;5;240m·\033[0m  Manage Tunnels                           \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[36m 3 \033[38;5;240m·\033[0m  Tunnel Status                            \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m                                                   \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[35m 4 \033[38;5;240m·\033[0m  Update Core                             \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[31m 5 \033[38;5;240m·\033[0m  Remove Core                             \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[90m 6 \033[38;5;240m·\033[0m  \033[90mSwitch Mode (Iran/Kharej)\033[0m                \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m                                                   \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m   \033[90m 0 \033[38;5;240m·\033[0m  \033[90mExit\033[0m                                    \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  │\033[0m                                                   \033[38;5;240m│\033[0m"
    echo -e "\033[38;5;240m  └─────────────────────────────────────────────────┘\033[0m"
    echo ""
    echo -ne "  \033[38;5;33m❯\033[0m  "
}

read_option() {
    read -r choice
    case $choice in
        1)
            if [[ "$SERVER_MODE" == "iran" ]]; then
                configure_tunnel_smart "server"
            elif [[ "$SERVER_MODE" == "abroad" ]]; then
                configure_tunnel_smart "client"
            fi ;;
        2) tunnel_management ;;
        3) check_tunnel_status ;;
        4) update_core ;;
        5) remove_core ;;
        6) select_server_mode ;;
        0)
            clear; echo ""
            echo -e "  \033[38;5;240m┌─────────────────────────────────────────────────┐\033[0m"
            echo -e "  \033[38;5;240m│\033[0m       \033[38;5;33mGoodbye · Thank you for using Tunnel\033[0m       \033[38;5;240m│\033[0m"
            echo -e "  \033[38;5;240m└─────────────────────────────────────────────────┘\033[0m"
            echo ""; exit 0 ;;
        *) echo -e "\n  \033[31m✗\033[0m  Invalid option."; sleep 1 ;;
    esac
}

# ─────────────────────────────────────────
# Entry Point
# ─────────────────────────────────────────

install_deps
detect_server_info
select_server_mode

# Auto-install binary
download_binary "$SERVER_MODE"

check_config_backup

while true; do
    display_menu
    read_option
done
