#!/usr/bin/env bash
#══════════════════════════════════════════════════════════════
#  Xray Reality Manager — TUI-based xray REALITY management
#══════════════════════════════════════════════════════════════

XRAY_BIN="/usr/local/bin/xray"
XRAY_SHARE_DIR="/usr/local/share/xray"
CONFIG_DIR="/usr/local/etc/xray"
CONFIG_FILE="$CONFIG_DIR/config.json"
DATA_FILE="$CONFIG_DIR/.reality-data"
XRAY_SERVICE="xray"
XRAY_SERVICE_FILE="/etc/systemd/system/xray.service"

RST="\033[0m"; BOLD="\033[1m"; DIM="\033[2m"
GREEN="\033[32m"; RED="\033[31m"; YELLOW="\033[33m"
CYAN="\033[36m"; WHITE="\033[97m"; REV="\033[7m"

MENU_ACTION=""

# ── Self-extracting payload support ──────────────────────────
_self_path() { readlink -f "$0" 2>/dev/null || echo "$0"; }
_has_payload() { grep -q '^__PAYLOAD__$' "$(_self_path)" 2>/dev/null; }
_self_extract() {
    local self; self=$(_self_path)
    local marker_line; marker_line=$(grep -an '^__PAYLOAD__$' "$self" | tail -1 | cut -d: -f1)
    [[ -z "$marker_line" ]] && { echo -e "  ${RED}✖ No embedded payload.${RST}"; return 1; }
    local tmp; tmp=$(mktemp -d)
    tail -n +"$(( marker_line + 1 ))" "$self" | tar xz -C "$tmp" \
        || { echo -e "  ${RED}✖ Extract failed.${RST}"; rm -rf "$tmp"; return 1; }
    [[ -x "$tmp/xray" ]] || { echo -e "  ${RED}✖ Payload missing xray binary.${RST}"; rm -rf "$tmp"; return 1; }

    sudo systemctl stop "$XRAY_SERVICE" 2>/dev/null || true
    sudo install -m 0755 "$tmp/xray" "$XRAY_BIN"
    sudo mkdir -p "$XRAY_SHARE_DIR" "$CONFIG_DIR" /var/log/xray
    [[ -f "$tmp/geoip.dat"   ]] && sudo install -m 0644 "$tmp/geoip.dat"   "$XRAY_SHARE_DIR/"
    [[ -f "$tmp/geosite.dat" ]] && sudo install -m 0644 "$tmp/geosite.dat" "$XRAY_SHARE_DIR/"
    if [[ -f "$tmp/xray.service" ]]; then
        sudo install -m 0644 "$tmp/xray.service" "$XRAY_SERVICE_FILE"
        sudo systemctl daemon-reload
    fi
    rm -rf "$tmp"
    return 0
}

# ── Terminal ─────────────────────────────────────────────────
hide_cursor()  { printf "\033[?25l"; }
show_cursor()  { printf "\033[?25h"; }
move_to()      { printf "\033[%d;%dH" "$1" "$2"; }
clear_line()   { printf "\033[2K"; }
clear_screen() { printf "\033[2J\033[H"; }

cleanup() { show_cursor; stty echo 2>/dev/null || true; tput sgr0 2>/dev/null || true; }
trap cleanup EXIT INT TERM

read_key() {
    local key=""
    IFS= read -rsn1 key 2>/dev/null || true
    if [[ "$key" == $'\x1b' ]]; then
        local seq=""
        IFS= read -rsn2 -t 0.1 seq 2>/dev/null || true
        case "$seq" in
            '[A') echo "UP"   ;; '[B') echo "DOWN" ;;
            '[C') echo "RIGHT";; '[D') echo "LEFT" ;;
            *) echo "ESC" ;;
        esac
    elif [[ "$key" == "" ]]; then echo "ENTER"
    elif [[ "$key" == "q" || "$key" == "Q" ]]; then echo "QUIT"
    elif [[ "$key" == "r" || "$key" == "R" ]]; then echo "REFRESH"
    else echo "$key"
    fi
}

# ── Drawing ──────────────────────────────────────────────────
draw_box() {
    local y="$1" x="$2" w="$3" h="$4" title="${5:-}" i
    move_to "$y" "$x"
    printf "${CYAN}╔"
    if [[ -n "$title" ]]; then
        printf "═ ${WHITE}${BOLD}%s${RST}${CYAN} " "$title"
        local tlen=$(( ${#title} + 4 ))
        for (( i=0; i < w-2-tlen; i++ )); do printf "═"; done
    else
        for (( i=0; i < w-2; i++ )); do printf "═"; done
    fi
    printf "╗${RST}"
    for (( i=1; i < h-1; i++ )); do
        move_to "$(( y+i ))" "$x"; printf "${CYAN}║${RST}"
        move_to "$(( y+i ))" "$(( x+w-1 ))"; printf "${CYAN}║${RST}"
    done
    move_to "$(( y+h-1 ))" "$x"
    printf "${CYAN}╚"
    for (( i=0; i < w-2; i++ )); do printf "═"; done
    printf "╝${RST}"
}

draw_hline() {
    local y="$1" x="$2" w="$3" i
    move_to "$y" "$x"; printf "${CYAN}╠"
    for (( i=0; i < w-2; i++ )); do printf "═"; done
    printf "╣${RST}"
}

# ── Helpers ──────────────────────────────────────────────────
is_installed() { [[ -x "$XRAY_BIN" ]]; }
xray_version() { is_installed && { "$XRAY_BIN" version 2>/dev/null | head -1 || echo "unknown"; } || echo "not installed"; }

get_status() {
    if systemctl is-active --quiet "$XRAY_SERVICE" 2>/dev/null; then echo "running"
    elif systemctl is-enabled --quiet "$XRAY_SERVICE" 2>/dev/null; then echo "stopped"
    else echo "disabled"; fi
}
status_icon() {
    case "$1" in running) echo "●";; stopped) echo "○";; disabled) echo "◌";; *) echo "?";; esac
}
status_color() {
    case "$1" in running) printf "${GREEN}";; stopped) printf "${YELLOW}";; disabled) printf "${RED}";; *) printf "${DIM}";; esac
}

get_proc_info() {
    local pid; pid=$(systemctl show -p MainPID --value "$XRAY_SERVICE" 2>/dev/null || echo "0")
    if [[ -z "$pid" ]] || [[ "$pid" == "0" ]]; then echo "- - - -"; return 0; fi
    local rss cpu etime
    rss=$(ps -p "$pid" -o rss= 2>/dev/null || echo "0")
    cpu=$(ps -p "$pid" -o %cpu= 2>/dev/null || echo "0")
    etime=$(ps -p "$pid" -o etime= 2>/dev/null || echo "-")
    rss=$(echo "$rss"|xargs); cpu=$(echo "$cpu"|xargs); etime=$(echo "$etime"|xargs)
    local rss_h
    if [[ "$rss" =~ ^[0-9]+$ ]] && [[ "$rss" -gt 1024 ]]; then rss_h="$(( rss/1024 ))M"; else rss_h="${rss}K"; fi
    echo "$pid $rss_h ${cpu}% $etime"
}

# ── Data persistence ─────────────────────────────────────────
save_data() {
    sudo tee "$DATA_FILE" > /dev/null << EOF
PRIVATE_KEY="$PRIVATE_KEY"
PUBLIC_KEY="$PUBLIC_KEY"
SHORT_ID="$SHORT_ID"
UUID="$UUID"
DEST="$DEST"
SERVER_NAME="$SERVER_NAME"
PORT="$PORT"
EOF
    sudo chmod 600 "$DATA_FILE"
}

load_data() {
    [[ -f "$DATA_FILE" ]] || return 1
    local line
    while IFS= read -r line; do
        case "$line" in
            PRIVATE_KEY=*)  PRIVATE_KEY="${line#*=}"; PRIVATE_KEY="${PRIVATE_KEY%\"}"; PRIVATE_KEY="${PRIVATE_KEY#\"}" ;;
            PUBLIC_KEY=*)   PUBLIC_KEY="${line#*=}"; PUBLIC_KEY="${PUBLIC_KEY%\"}"; PUBLIC_KEY="${PUBLIC_KEY#\"}" ;;
            SHORT_ID=*)     SHORT_ID="${line#*=}"; SHORT_ID="${SHORT_ID%\"}"; SHORT_ID="${SHORT_ID#\"}" ;;
            UUID=*)         UUID="${line#*=}"; UUID="${UUID%\"}"; UUID="${UUID#\"}" ;;
            DEST=*)         DEST="${line#*=}"; DEST="${DEST%\"}"; DEST="${DEST#\"}" ;;
            SERVER_NAME=*)  SERVER_NAME="${line#*=}"; SERVER_NAME="${SERVER_NAME%\"}"; SERVER_NAME="${SERVER_NAME#\"}" ;;
            PORT=*)         PORT="${line#*=}"; PORT="${PORT%\"}"; PORT="${PORT#\"}" ;;
        esac
    done < <(sudo cat "$DATA_FILE" 2>/dev/null)
    [[ -n "$PRIVATE_KEY" ]] && return 0 || return 1
}

# ── Key generation (with validation) ─────────────────────────
generate_keys() {
    if ! is_installed; then
        echo -e "  ${RED}✖ Xray not installed.${RST}"; return 1
    fi

    echo -e "  ${CYAN}Generating x25519 keypair...${RST}"
    local output
    output=$("$XRAY_BIN" x25519 2>/dev/null)
    PRIVATE_KEY=$(echo "$output" | grep -i "private" | awk '{print $NF}')
    PUBLIC_KEY=$(echo "$output" | grep -i "public" | awk '{print $NF}')

    if [[ -z "$PRIVATE_KEY" ]] || [[ -z "$PUBLIC_KEY" ]]; then
        echo -e "  ${RED}✖ Key generation failed.${RST}"
        echo -e "  ${DIM}Raw output: ${output}${RST}"
        return 1
    fi

    echo -e "  ${CYAN}Generating Short ID...${RST}"
    SHORT_ID=$(openssl rand -hex 8)

    echo -e "  ${CYAN}Generating UUID...${RST}"
    UUID=$("$XRAY_BIN" uuid 2>/dev/null)
    if [[ -z "$UUID" ]]; then
        UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen 2>/dev/null)
    fi

    echo ""
    echo -e "  Private Key : ${YELLOW}${PRIVATE_KEY}${RST}"
    echo -e "  Public Key  : ${YELLOW}${PUBLIC_KEY}${RST}"
    echo -e "  Short ID    : ${YELLOW}${SHORT_ID}${RST}"
    echo -e "  UUID        : ${YELLOW}${UUID}${RST}"
    echo ""
    return 0
}

# ── Dest selection ───────────────────────────────────────────
PICK_RESULT=-1
_arrow_pick() {
    local title="$1" cur="${2:-0}"
    shift 2
    local pick_items=("$@")
    local count=${#pick_items[@]}
    [[ $count -eq 0 ]] && { PICK_RESULT=-1; return 1; }
    [[ $cur -ge $count ]] && cur=0
    local term_h; term_h=$(tput lines 2>/dev/null || echo 24)
    local page=$(( term_h - 7 ))
    [[ $page -lt 5 ]] && page=5
    [[ $page -gt $count ]] && page=$count
    local off=0 w=60 sx=3 sy=2 h=$(( page + 2 ))
    local ry=$(( sy + 1 )) cx=$(( sx + 2 )) iw=$(( w - 4 ))
    if [[ $cur -ge $page ]]; then off=$(( cur - page + 1 )); fi
    clear_screen; hide_cursor
    draw_box $sy $sx $w $h "$title"
    _pk_draw() {
        for (( ri = 0; ri < page; ri++ )); do
            local i=$(( off + ri )) y=$(( ry + ri ))
            move_to "$y" "$(( cx - 1 ))"; printf "${CYAN}║${RST}"
            move_to "$y" "$(( cx + iw ))"; printf "${CYAN}║${RST}"
            move_to "$y" "$cx"
            if [[ $i -lt $count ]]; then
                if [[ $i -eq $cur ]]; then
                    printf "${REV}${BOLD} ▸ %-$(( iw - 3 ))s${RST}" "${pick_items[$i]}"
                else
                    printf "   %-$(( iw - 3 ))s" "${pick_items[$i]}"
                fi
            else printf "%-${iw}s" ""; fi
        done
        move_to $(( sy + h + 1 )) $sx; clear_line
        printf "${DIM}  ↑↓ Navigate  Enter Select  q Cancel${RST}"
    }
    _pk_draw
    while true; do
        local key; key=$(read_key)
        case "$key" in
            UP)   [[ $cur -gt 0 ]] && (( cur-- )) ;;
            DOWN) [[ $cur -lt $(( count-1 )) ]] && (( cur++ )) ;;
            ENTER)    PICK_RESULT=$cur; return 0 ;;
            QUIT|ESC) PICK_RESULT=-1;   return 1 ;;
            *) continue ;;
        esac
        if [[ $cur -lt $off ]]; then off=$cur; fi
        if [[ $cur -ge $(( off + page )) ]]; then off=$(( cur - page + 1 )); fi
        _pk_draw
    done
}

select_dest() {
    local sites=(
        "www.microsoft.com"
        "www.apple.com"
        "www.samsung.com"
        "www.logitech.com"
        "www.nvidia.com"
        "Custom..."
    )
    _arrow_pick "Select Dest Site" 0 "${sites[@]}" || return 1

    if [[ $PICK_RESULT -eq 5 ]]; then
        show_cursor
        read -rp "  Domain (e.g. www.example.com): " SERVER_NAME
        [[ -z "$SERVER_NAME" ]] && return 1
    else
        SERVER_NAME="${sites[$PICK_RESULT]}"
    fi
    DEST="${SERVER_NAME}:443"

    show_cursor
    echo -e "\n  ${CYAN}Verifying TLS 1.3 for ${SERVER_NAME}...${RST}"
    if curl -sI --tlsv1.3 --max-time 5 "https://$SERVER_NAME" > /dev/null 2>&1; then
        echo -e "  ${GREEN}✔ TLS 1.3 OK${RST}"
    else
        echo -e "  ${YELLOW}⚠ TLS 1.3 verification failed — may still work.${RST}"
        read -rp "  Continue? [Y/n]: " cont
        [[ "${cont,,}" == "n" ]] && return 1
    fi
    return 0
}

# ── Config writing ───────────────────────────────────────────
write_config() {
    sudo mkdir -p "$CONFIG_DIR"
    sudo tee "$CONFIG_FILE" > /dev/null << EOF
{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": $PORT,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "$UUID",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "dest": "$DEST",
          "serverNames": [
            "$SERVER_NAME"
          ],
          "privateKey": "$PRIVATE_KEY",
          "shortIds": [
            "$SHORT_ID"
          ]
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    }
  ]
}
EOF
}

# ── Deploy ───────────────────────────────────────────────────
do_deploy() {
    clear_screen; show_cursor
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}"
    echo -e "${BOLD}  Deploy Xray Reality${RST}"
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}\n"

    if ! is_installed; then
        echo -e "  ${RED}✖ Xray not installed. Install first.${RST}"
        read -rp "  Press Enter..."; return
    fi

    # Check existing data
    if load_data 2>/dev/null; then
        echo -e "  ${YELLOW}Existing config found:${RST}"
        echo -e "  UUID : ${DIM}${UUID}${RST}"
        echo -e "  Dest : ${DIM}${SERVER_NAME}${RST}"
        echo -e "  Port : ${DIM}${PORT}${RST}\n"
        read -rp "  Use existing keys? [Y/n]: " choice
        if [[ "${choice,,}" == "n" ]]; then
            generate_keys || { read -rp "  Press Enter..."; return; }
            hide_cursor
            select_dest || { show_cursor; read -rp "  Press Enter..."; return; }
            show_cursor
        fi
    else
        generate_keys || { read -rp "  Press Enter..."; return; }
        hide_cursor
        select_dest || { show_cursor; read -rp "  Press Enter..."; return; }
        show_cursor
    fi

    read -rp "  Listen port [443]: " input_port
    PORT=${input_port:-443}

    # Validate privateKey before writing
    if [[ -z "$PRIVATE_KEY" ]]; then
        echo -e "  ${RED}✖ Private key is empty! Run deploy again.${RST}"
        read -rp "  Press Enter..."; return
    fi

    echo -e "\n  ${CYAN}Writing config...${RST}"
    write_config
    save_data

    # Firewall
    if command -v ufw &>/dev/null; then
        sudo ufw allow "$PORT/tcp" 2>/dev/null && echo -e "  ${GREEN}✔ UFW: allowed ${PORT}/tcp${RST}"
    fi

    echo -e "  ${CYAN}Starting xray...${RST}"
    sudo systemctl enable --now "$XRAY_SERVICE" 2>/dev/null
    sleep 1

    if systemctl is-active --quiet "$XRAY_SERVICE"; then
        echo -e "  ${GREEN}✔ Xray running!${RST}\n"
        _show_client_config_inline
    else
        echo -e "  ${RED}✖ Failed to start. Recent logs:${RST}\n"
        journalctl -u "$XRAY_SERVICE" --no-pager -n 10 2>/dev/null
    fi
    read -rp "  Press Enter..."
}

# ── Client config ────────────────────────────────────────────
_show_client_config_inline() {
    local server_ip
    server_ip=$(curl -s4 --max-time 3 ifconfig.me 2>/dev/null || echo "<YOUR_SERVER_IP>")

    echo -e "  ${BOLD}${CYAN}Clash Meta / Clash Verge Rev:${RST}\n"
    echo "  - name: reality-node"
    echo "    type: vless"
    echo "    server: $server_ip"
    echo "    port: $PORT"
    echo "    uuid: $UUID"
    echo "    network: tcp"
    echo "    tls: true"
    echo "    udp: true"
    echo "    flow: xtls-rprx-vision"
    echo "    client-fingerprint: chrome"
    echo "    reality-opts:"
    echo "      public-key: $PUBLIC_KEY"
    echo "      short-id: $SHORT_ID"
    echo "    servername: $SERVER_NAME"
    echo ""
    echo -e "  ${BOLD}Compact:${RST}"
    echo "  - {name: reality-node, type: vless, server: $server_ip, port: $PORT, uuid: $UUID, network: tcp, tls: true, udp: true, flow: xtls-rprx-vision, client-fingerprint: chrome, reality-opts: {public-key: $PUBLIC_KEY, short-id: $SHORT_ID}, servername: $SERVER_NAME}"
    echo ""
}

do_client_config() {
    clear_screen; show_cursor
    if ! load_data 2>/dev/null; then
        echo -e "\n  ${RED}✖ No config data. Deploy first.${RST}"
        read -rp "  Press Enter..."; return
    fi
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}"
    echo -e "${BOLD}  Client Config${RST}"
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}\n"
    _show_client_config_inline
    read -rp "  Press Enter..."
}

# ── Show keys/info ───────────────────────────────────────────
do_show_info() {
    clear_screen; show_cursor
    if ! load_data 2>/dev/null; then
        echo -e "\n  ${RED}✖ No config data. Deploy first.${RST}"
        read -rp "  Press Enter..."; return
    fi
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}"
    echo -e "${BOLD}  Keys & Config${RST}"
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}\n"
    echo -e "  UUID        : ${YELLOW}${UUID}${RST}"
    echo -e "  Private Key : ${YELLOW}${PRIVATE_KEY}${RST}"
    echo -e "  Public Key  : ${YELLOW}${PUBLIC_KEY}${RST}"
    echo -e "  Short ID    : ${YELLOW}${SHORT_ID}${RST}"
    echo -e "  Dest        : ${YELLOW}${SERVER_NAME}${RST}"
    echo -e "  Port        : ${YELLOW}${PORT}${RST}"
    echo ""
    read -rp "  Press Enter..."
}

# ── Change dest ──────────────────────────────────────────────
do_change_dest() {
    if ! load_data 2>/dev/null; then
        clear_screen; show_cursor
        echo -e "\n  ${RED}✖ No config data. Deploy first.${RST}"
        read -rp "  Press Enter..."; return
    fi
    select_dest || return
    show_cursor
    echo -e "\n  ${CYAN}Updating config...${RST}"
    write_config
    save_data
    sudo systemctl restart "$XRAY_SERVICE" 2>/dev/null
    sleep 1
    if systemctl is-active --quiet "$XRAY_SERVICE"; then
        echo -e "  ${GREEN}✔ Switched to ${SERVER_NAME}${RST}"
    else
        echo -e "  ${RED}✖ Restart failed.${RST}"
    fi
    read -rp "  Press Enter..."
}

# ── Regen keys ───────────────────────────────────────────────
do_regen_keys() {
    clear_screen; show_cursor
    if ! load_data 2>/dev/null; then
        echo -e "\n  ${RED}✖ No config data. Deploy first.${RST}"
        read -rp "  Press Enter..."; return
    fi
    echo -e "\n  ${YELLOW}⚠ All clients will need updated config after this.${RST}"
    read -rp "  Continue? [y/N]: " choice
    [[ "${choice,,}" != "y" ]] && return

    generate_keys || { read -rp "  Press Enter..."; return; }
    write_config
    save_data

    sudo systemctl restart "$XRAY_SERVICE" 2>/dev/null
    sleep 1
    if systemctl is-active --quiet "$XRAY_SERVICE"; then
        echo -e "  ${GREEN}✔ Keys updated, xray restarted.${RST}\n"
        _show_client_config_inline
    else
        echo -e "  ${RED}✖ Restart failed.${RST}"
    fi
    read -rp "  Press Enter..."
}

# ── Install ──────────────────────────────────────────────────
do_install() {
    clear_screen; show_cursor
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}"
    echo -e "${BOLD}  Install / Update Xray${RST}"
    echo -e "${BOLD}${CYAN}══════════════════════════════════════════════════${RST}\n"

    if is_installed; then
        echo -e "  Current: ${GREEN}$(xray_version)${RST}"
    else
        echo -e "  Current: ${RED}not installed${RST}"
    fi
    echo -e "  Binary:  ${CYAN}${XRAY_BIN}${RST}"
    echo -e "  Config:  ${CYAN}${CONFIG_DIR}/${RST}\n"

    echo -e "  ${BOLD}Source:${RST}"
    if _has_payload; then
        echo "    1) Extract from this script (offline)"
        echo "    2) Official Xray-install (online)"
        echo "    3) Cancel"
    else
        echo "    1) Official Xray-install (online)"
        echo "    2) Cancel"
    fi
    echo ""
    read -rp "  Choice [1]: " src; src=${src:-1}

    if _has_payload; then
        case "$src" in
            1)
                echo -e "\n  ${CYAN}↻ Extracting embedded payload...${RST}"
                if _self_extract; then
                    echo -e "\n  ${GREEN}✔ $(xray_version)${RST}"
                    echo -e "  ${DIM}Binary:  ${XRAY_BIN}${RST}"
                    echo -e "  ${DIM}Share:   ${XRAY_SHARE_DIR}/${RST}"
                    echo -e "  ${DIM}Service: ${XRAY_SERVICE_FILE}${RST}"
                else
                    echo -e "  ${RED}✖ Extraction failed.${RST}"
                fi
                read -rp "  Press Enter..."; return ;;
            2) ;;  # fall through to online
            *) return ;;
        esac
    else
        [[ "$src" == "2" ]] && return
    fi

    if ! command -v curl &>/dev/null; then
        echo -e "  ${RED}✖ curl required.${RST}"
        read -rp "  Press Enter..."; return
    fi

    echo -e "\n  ${DIM}Using the official Xray install script...${RST}\n"
    sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

    if [[ -x "$XRAY_BIN" ]]; then
        echo -e "\n  ${GREEN}✔ $(xray_version)${RST}"
    else
        echo -e "\n  ${RED}✖ Install failed.${RST}"
    fi
    read -rp "  Press Enter..."
}

# ═══════════════════════════════════════════════════════════════
#  Arrow menu
# ═══════════════════════════════════════════════════════════════
_draw_row() {
    local idx="$1" sel="$2" ry="$3" cx="$4" w="$5"
    move_to "$(( ry + idx ))" "$cx"
    clear_line
    move_to "$(( ry + idx ))" "$(( cx - 1 ))"; printf "${CYAN}║${RST}"
    move_to "$(( ry + idx ))" "$(( cx + w ))";  printf "${CYAN}║${RST}"
    move_to "$(( ry + idx ))" "$cx"
    if [[ "${types[$idx]}" == "hdr" ]]; then
        printf "${DIM}${BOLD}%-${w}s${RST}" "${items[$idx]}"
    elif [[ "$idx" -eq "$sel" ]]; then
        printf "${REV}${BOLD} ▸ %-$(( w - 3 ))s${RST}" "${items[$idx]}"
    else
        printf "   %-$(( w - 3 ))s" "${items[$idx]}"
    fi
}

_next_sel() {
    local cur="$1" dir="$2" total="$3" pos=$1
    while true; do
        pos=$(( pos + dir ))
        if [[ $pos -lt 0 ]] || [[ $pos -ge $total ]]; then echo "$cur"; return; fi
        if [[ "${types[$pos]}" != "hdr" ]]; then echo "$pos"; return; fi
    done
}

arrow_menu() {
    local -n _sel="$1"
    local ry="$2" cx="$3" w="$4"
    local total=${#items[@]}
    if [[ "${types[$_sel]}" == "hdr" ]]; then _sel=$(_next_sel "$_sel" 1 "$total"); fi
    local i; for i in "${!items[@]}"; do _draw_row "$i" "$_sel" "$ry" "$cx" "$w"; done
    while true; do
        local key; key=$(read_key)
        case "$key" in
            UP)   local ns; ns=$(_next_sel "$_sel" -1 "$total")
                  if [[ "$ns" -ne "$_sel" ]]; then local old=$_sel; _sel=$ns
                      _draw_row "$old" "$_sel" "$ry" "$cx" "$w"
                      _draw_row "$_sel" "$_sel" "$ry" "$cx" "$w"; fi ;;
            DOWN) local ns; ns=$(_next_sel "$_sel" 1 "$total")
                  if [[ "$ns" -ne "$_sel" ]]; then local old=$_sel; _sel=$ns
                      _draw_row "$old" "$_sel" "$ry" "$cx" "$w"
                      _draw_row "$_sel" "$_sel" "$ry" "$cx" "$w"; fi ;;
            ENTER|QUIT|ESC|REFRESH) MENU_ACTION="$key"; return ;;
        esac
    done
}

# ═══════════════════════════════════════════════════════════════
#  Main menu
# ═══════════════════════════════════════════════════════════════
main_menu() {
    local sel=0
    local need_full=1
    local items=()
    local types=()
    local menu_row=0 menu_col=0 menu_w=0

    while true; do
        if [[ $need_full -eq 1 ]]; then
            clear_screen; hide_cursor

            local status; status=$(get_status)
            local enabled="no"
            systemctl is-enabled --quiet "$XRAY_SERVICE" 2>/dev/null && enabled="yes"
            local pi pid rss cpu etime
            pi=$(get_proc_info)
            pid=$(echo "$pi"|awk '{print $1}'); rss=$(echo "$pi"|awk '{print $2}')
            cpu=$(echo "$pi"|awk '{print $3}'); etime=$(echo "$pi"|awk '{print $4}')

            local dest_short="(not deployed)"
            load_data 2>/dev/null && dest_short="$SERVER_NAME"

            items=(); types=()
            items+=("Start");           types+=("act")
            items+=("Stop");            types+=("act")
            items+=("Restart");         types+=("act")
            items+=("Enable (boot)");   types+=("act")
            items+=("Disable (boot)");  types+=("act")
            items+=("Status");          types+=("act")
            items+=(""); types+=("hdr")
            items+=("─── Reality ───"); types+=("hdr")
            items+=("Deploy / Setup");       types+=("act")
            items+=("Show Keys & Info");     types+=("act")
            items+=("Client Config");        types+=("act")
            items+=("Change Dest Site");     types+=("act")
            items+=("Regenerate Keys");      types+=("act")
            items+=(""); types+=("hdr")
            items+=("─── Other ───"); types+=("hdr")
            items+=("View Config");          types+=("act")
            items+=("View Logs");            types+=("act")
            items+=("Install / Update Xray"); types+=("act")
            items+=("Uninstall");            types+=("act")
            items+=(""); types+=("hdr")
            items+=("Quit"); types+=("act")

            local total=${#items[@]}
            if [[ $sel -ge $total ]]; then sel=$(( total-1 )); fi
            if [[ $sel -lt 0 ]]; then sel=0; fi

            local w=60 sx=3 sy=2
            local h=$(( total + 9 ))
            draw_box $sy $sx $w $h "Xray Reality Manager"

            local row=$(( sy+1 ))
            local ver; ver=$(xray_version)
            local vc="${GREEN}"; is_installed || vc="${RED}"
            move_to $row $(( sx+3 ))
            printf "${DIM}xray: ${vc}%s${RST}" "$ver"
            row=$(( row+1 ))
            move_to $row $(( sx+3 ))
            printf "Status : $(status_color "$status")$(status_icon "$status") %-10s${RST}   Boot: %-5s" "$status" "$enabled"
            row=$(( row+1 ))
            move_to $row $(( sx+3 ))
            printf "PID    : %-8s   MEM: %-8s" "$pid" "$rss"
            row=$(( row+1 ))
            move_to $row $(( sx+3 ))
            printf "CPU    : %-8s   Uptime: %s" "$cpu" "$etime"
            row=$(( row+1 ))
            move_to $row $(( sx+3 ))
            printf "${DIM}Dest   : %s${RST}" "$dest_short"
            row=$(( row+1 ))
            move_to $row $(( sx+3 ))
            printf "${DIM}Config : %s${RST}" "$CONFIG_FILE"
            row=$(( row+1 ))
            draw_hline $row $sx $w
            row=$(( row+1 ))

            menu_row=$row; menu_col=$(( sx+2 )); menu_w=$(( w-4 ))

            move_to $(( sy+h+1 )) $sx
            printf "${DIM}  ↑↓ Navigate   Enter Select   r Refresh   q Quit${RST}"

            need_full=0
            arrow_menu sel "$menu_row" "$menu_col" "$menu_w"
        else
            arrow_menu sel "$menu_row" "$menu_col" "$menu_w"
        fi

        case "$MENU_ACTION" in
            QUIT|ESC) clear_screen; show_cursor; exit 0 ;;
            REFRESH)  need_full=1; continue ;;
            ENTER)
                case $sel in
                    0) sudo systemctl start   "$XRAY_SERVICE" 2>/dev/null; need_full=1 ;;
                    1) sudo systemctl stop    "$XRAY_SERVICE" 2>/dev/null; need_full=1 ;;
                    2) sudo systemctl restart "$XRAY_SERVICE" 2>/dev/null; need_full=1 ;;
                    3) sudo systemctl enable  "$XRAY_SERVICE" 2>/dev/null; need_full=1 ;;
                    4) sudo systemctl disable "$XRAY_SERVICE" 2>/dev/null; need_full=1 ;;
                    5) # Status
                       clear_screen; show_cursor
                       echo -e "${BOLD}${CYAN}  Status: xray${RST}\n"
                       if ! systemctl is-enabled --quiet "$XRAY_SERVICE" 2>/dev/null; then
                           echo -e "  ${YELLOW}⚠ Not enabled at boot.${RST}\n"
                       fi
                       systemctl status "$XRAY_SERVICE" --no-pager -l 2>/dev/null || echo "  Service not found."
                       echo ""; read -rp "  Press Enter..."
                       hide_cursor; need_full=1 ;;
                    8)  do_deploy;        hide_cursor; need_full=1 ;;
                    9)  do_show_info;     hide_cursor; need_full=1 ;;
                    10) do_client_config; hide_cursor; need_full=1 ;;
                    11) do_change_dest;   hide_cursor; need_full=1 ;;
                    12) do_regen_keys;    hide_cursor; need_full=1 ;;
                    15) # View Config
                       clear_screen; show_cursor
                       echo -e "${BOLD}${CYAN}  ${CONFIG_FILE}${RST}\n"
                       [[ -f "$CONFIG_FILE" ]] && sudo cat -n "$CONFIG_FILE" || echo "  Not found."
                       echo ""; read -rp "  Press Enter..."
                       hide_cursor; need_full=1 ;;
                    16) # View Logs
                       clear_screen; show_cursor
                       echo -e "${BOLD}${CYAN}  Logs: xray${RST}  ${DIM}(last 50)${RST}\n"
                       journalctl -u "$XRAY_SERVICE" -n 50 --no-pager -o short-iso 2>/dev/null || echo "  No logs."
                       echo ""; read -rp "  Press Enter..."
                       hide_cursor; need_full=1 ;;
                    17) do_install; hide_cursor; need_full=1 ;;
                    18) # Uninstall
                       clear_screen; show_cursor
                       echo -e "\n  ${RED}${BOLD}⚠ Uninstall Xray?${RST}"
                       echo -e "  ${DIM}Stops service, removes binary + config.${RST}"
                       read -rp "  Type 'yes': " confirm
                       if [[ "$confirm" == "yes" ]]; then
                           sudo systemctl stop "$XRAY_SERVICE" 2>/dev/null || true
                           sudo systemctl disable "$XRAY_SERVICE" 2>/dev/null || true
                           sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ remove 2>/dev/null
                           sudo rm -rf "$CONFIG_DIR"
                           echo -e "  ${GREEN}✔ Uninstalled.${RST}"
                       else echo -e "  ${YELLOW}Cancelled.${RST}"; fi
                       sleep 1; hide_cursor; need_full=1 ;;
                    20) clear_screen; show_cursor; exit 0 ;;
                esac
                ;;
        esac
    done
}

# ═══════════════════════════════════════════════════════════════
#  CLI
# ═══════════════════════════════════════════════════════════════
cli_usage() {
    cat <<EOF
Usage: $(basename "$0") [command]

  (no args)     Interactive TUI
  deploy        Deploy / setup Reality
  info          Show keys & config
  client        Show client config
  dest          Change dest site
  rekey         Regenerate keys
  start         Start xray
  stop          Stop xray
  restart       Restart xray
  status        Show service status
  logs          Tail logs
  install       Install / update xray
  uninstall     Remove xray

Paths:
  Binary:  ${XRAY_BIN}
  Config:  ${CONFIG_FILE}
  Data:    ${DATA_FILE}
  Service: ${XRAY_SERVICE}.service
EOF
}

main() {
    if [[ $# -eq 0 ]]; then main_menu; exit 0; fi
    case "$1" in
        deploy|setup)  do_deploy ;;
        info|show)     do_show_info ;;
        client)        do_client_config ;;
        dest)          do_change_dest ;;
        rekey)         do_regen_keys ;;
        start)         sudo systemctl start "$XRAY_SERVICE"; echo -e "${GREEN}✔ started${RST}" ;;
        stop)          sudo systemctl stop "$XRAY_SERVICE"; echo -e "${GREEN}✔ stopped${RST}" ;;
        restart)       sudo systemctl restart "$XRAY_SERVICE"; echo -e "${GREEN}✔ restarted${RST}" ;;
        status)        systemctl status "$XRAY_SERVICE" --no-pager ;;
        logs)          journalctl -u "$XRAY_SERVICE" -n 100 --no-pager -f ;;
        install)       do_install ;;
        uninstall)
            echo -e "${RED}⚠ This will remove Xray and all config.${RST}"
            read -rp "Type 'yes': " confirm
            [[ "$confirm" == "yes" ]] || exit 0
            sudo systemctl stop "$XRAY_SERVICE" 2>/dev/null || true
            sudo systemctl disable "$XRAY_SERVICE" 2>/dev/null || true
            sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ remove
            sudo rm -rf "$CONFIG_DIR"
            echo -e "${GREEN}✔ Uninstalled.${RST}" ;;
        -h|--help|help) cli_usage ;;
        *) echo -e "${RED}Unknown: $1${RST}"; cli_usage; exit 1 ;;
    esac
}

main "$@"
