#!/bin/bash

# XNEXX Agent Installation Script (TLS+WS)
# Установка: curl -sSL https://nexios.ru/xnexx/install.sh | DOMAIN=xx.nexios.ru bash

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

COUNTRY=$(curl -s --max-time 5 https://ipinfo.io/country 2>/dev/null || echo "RU")
if [ "$COUNTRY" = "RU" ]; then
    NEXIOS_URL="https://nexios.ru"
    FALLBACK_URL="https://am-mj-1.nexios.ru"
else
    NEXIOS_URL="https://am-mj-1.nexios.ru"
    FALLBACK_URL="https://nexios.ru"
fi
INSTALL_DIR="/opt/xnexx-agent"
MIN_SPEED=102400
echo "[INFO] Регион: $COUNTRY, primary: $NEXIOS_URL"

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }

download_file() {
    local filename="$1"
    local output="$2"
    local url1="$NEXIOS_URL/xnexx/$filename"
    local url2="$FALLBACK_URL/xnexx/$filename"

    log_info "Скачиваем $filename..."

    local speed=$(curl -#L --max-time 15 -o "$output" -w "%{speed_download}" "$url1" || echo "0")
    speed=${speed%.*}

    if [ -f "$output" ] && [ -s "$output" ] && [ "$speed" -gt "$MIN_SPEED" ]; then
        log_info "$filename скачан с nexios.ru"
        return 0
    fi

    log_warn "$filename медленно с nexios.ru, пробуем am-mj-1..."
    rm -f "$output"

    curl -#L --max-time 120 -o "$output" "$url2"

    if [ -f "$output" ] && [ -s "$output" ]; then
        log_info "$filename скачан с am-mj-1"
        return 0
    fi

    log_error "Не удалось скачать $filename"
}

if [ "$EUID" -ne 0 ]; then
    log_error "Запустите скрипт от root"
fi

# ========== Проверка домена ==========
if [ -z "$DOMAIN" ]; then
    log_error "Не указан домен. Использование: DOMAIN=xx.nexios.ru curl -sSL https://nexios.ru/xnexx/install.sh | bash"
fi

log_info "Установка XNEXX Agent (TLS+WebSocket)..."
log_info "Домен: $DOMAIN"

OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case $ARCH in
    x86_64) ARCH="amd64" ;;
    aarch64|arm64) ARCH="arm64" ;;
    *) log_error "Неподдерживаемая архитектура: $ARCH" ;;
esac
log_info "Система: $OS/$ARCH"

if ! command -v curl &> /dev/null; then
    log_error "curl не найден. Установите: apt install curl"
fi

SERVER_ID="xvps-$(hostname)-$(date +%s | tail -c 5)"

# ========== Установка certbot ==========
log_info "Устанавливаем базовые пакеты..."
DEBIAN_FRONTEND=noninteractive apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq cron certbot curl wget jq sqlite3 openssl > /dev/null 2>&1
systemctl enable cron 2>/dev/null && systemctl start cron 2>/dev/null

# ========== Создание директорий ==========
log_info "Создаем директории..."
mkdir -p $INSTALL_DIR/data
mkdir -p $INSTALL_DIR/configs
mkdir -p /etc/sing-box
mkdir -p /var/log

# ========== Скачивание файлов ==========
download_file "xnexx-agent" "$INSTALL_DIR/xnexx-agent"
chmod +x $INSTALL_DIR/xnexx-agent

download_file "auto-update.sh" "$INSTALL_DIR/auto-update.sh"
chmod +x $INSTALL_DIR/auto-update.sh 2>/dev/null || true

download_file "sing-box" "/usr/bin/sing-box"
chmod +x /usr/bin/sing-box
log_info "sing-box установлен"

# ========== Определение IP ==========
log_info "Определяем IP..."
VPS_IP=$(curl -s https://api.ipify.org 2>/dev/null || curl -s https://ifconfig.me 2>/dev/null || echo "127.0.0.1")
log_info "IP: $VPS_IP"

# ========== Получение SSL сертификата ==========
log_info "Получаем SSL сертификат для $DOMAIN..."

# Убиваем всё на 80 порту
fuser -k 80/tcp 2>/dev/null || true
sleep 1

CERT_PATH="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
KEY_PATH="/etc/letsencrypt/live/$DOMAIN/privkey.pem"

if [ -f "$CERT_PATH" ] && [ -f "$KEY_PATH" ]; then
    log_info "Сертификат уже существует"
else
    certbot certonly --standalone -d "$DOMAIN" --non-interactive --agree-tos -m admin@nexios.ru --preferred-challenges http
    if [ $? -eq 0 ]; then
        log_info "Сертификат получен"
    else
        log_error "Не удалось получить сертификат. Проверьте что DNS $DOMAIN указывает на $VPS_IP"
    fi
fi

# Права на сертификаты для sing-box
chmod 755 /etc/letsencrypt/live/ /etc/letsencrypt/archive/ 2>/dev/null || true
chmod 644 /etc/letsencrypt/archive/$DOMAIN/*.pem 2>/dev/null || true

# ========== Конфигурация ==========
log_info "Создаем конфигурацию..."
cat > $INSTALL_DIR/config.yaml <<EOF
server:
    port: "8080"
    whitelist_ips:
        - "127.0.0.1"
        - "$VPS_IP"
        - "95.165.98.239"
        - "158.255.1.15"

singbox:
    config_path: "/etc/sing-box/config.json"
    binary_path: "/usr/bin/sing-box"
    server_ip: "$VPS_IP"
    server_port: 443
    domain: "$DOMAIN"
    cert_path: "$CERT_PATH"
    key_path: "$KEY_PATH"
    ws_path: "/ws"
    max_blocked: true

nexios:
    url: "https://nexios.ru"
    server_id: "$SERVER_ID"

database:
    path: "$INSTALL_DIR/data/nexx.db"
EOF

# Начальный sing-box конфиг (будет перезаписан агентом)
cat > /etc/sing-box/config.json <<EOF
{
  "log": {"level": "info", "output": "/var/log/sing-box.log"},
  "inbounds": [],
  "outbounds": [{"type": "direct", "tag": "direct"}]
}
EOF

# ========== Systemd сервисы ==========
log_info "Создаем systemd службы..."

cat > /etc/systemd/system/xnexx-agent.service <<EOF
[Unit]
Description=XNEXX Agent (TLS+WS)
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/xnexx-agent
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

cat > /etc/systemd/system/sing-box.service <<EOF
[Unit]
Description=sing-box
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/sing-box run -c /etc/sing-box/config.json
ExecReload=/bin/kill -HUP \$MAINPID
Restart=on-failure
RestartSec=10
LimitNOFILE=infinity
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

# ========== Cron: автообновление + certbot ==========
log_info "Настраиваем автообновление и certbot..."

CRON_AGENT="0 * * * * $INSTALL_DIR/auto-update.sh >> /var/log/xnexx-agent-update.log 2>&1"
CRON_CERT="0 3 * * * certbot renew --quiet --deploy-hook 'systemctl restart sing-box'"

{ crontab -l 2>/dev/null | grep -v "auto-update.sh" | grep -v "certbot renew" || true; echo "$CRON_AGENT"; echo "$CRON_CERT"; } | crontab -

# ========== Blacklist ==========
log_info "Настраиваем blacklist..."
cat > $INSTALL_DIR/update-blacklist.sh << 'SCRIPT_END'
#!/bin/bash
BLACKLIST_URL="https://nexios.ru/black.lst"
LOCAL_FILE="/opt/xnexx-agent/black.lst"
BACKUP_FILE="/opt/xnexx-agent/black.lst.backup"
TEMP_FILE="/tmp/black.lst.tmp"

if ! curl -sf "$BLACKLIST_URL" -o "$TEMP_FILE"; then
    [ -f "$BACKUP_FILE" ] && cp "$BACKUP_FILE" "$LOCAL_FILE"
    exit 0
fi

REMOTE_HASH=$(md5sum "$TEMP_FILE" | awk '{print $1}')
LOCAL_HASH=$([ -f "$LOCAL_FILE" ] && md5sum "$LOCAL_FILE" | awk '{print $1}')

[ "$REMOTE_HASH" = "$LOCAL_HASH" ] && exit 0

if ! grep -vE '^(#|$)' "$TEMP_FILE" | grep -qE '^[a-zA-Z0-9.-]+$'; then
    echo "ERROR: Invalid domains format"
    exit 1
fi

mv "$TEMP_FILE" "$LOCAL_FILE"
cp "$LOCAL_FILE" "$BACKUP_FILE"

curl -sf http://localhost:8080/api/sync/trigger -X POST
echo "Blacklist updated"
SCRIPT_END

chmod +x $INSTALL_DIR/update-blacklist.sh

BLACKLIST_CRON="*/15 * * * * $INSTALL_DIR/update-blacklist.sh >> /var/log/blacklist-update.log 2>&1"
{ crontab -l 2>/dev/null | grep -v "update-blacklist.sh" || true; echo "$BLACKLIST_CRON"; } | crontab -

log_info "Загружаем blacklist..."
$INSTALL_DIR/update-blacklist.sh 2>/dev/null || true

# ========== Запуск ==========
systemctl daemon-reload

log_info "Запускаем службы..."
systemctl enable xnexx-agent 2>/dev/null
systemctl start xnexx-agent || log_error "Не удалось запустить агент"

systemctl enable sing-box 2>/dev/null
systemctl start sing-box

sleep 2
if systemctl is-active --quiet xnexx-agent; then
    log_info "Агент запущен"
else
    log_error "Агент не запустился. Логи: journalctl -u xnexx-agent -n 50"
fi

# WAL режим
log_info "Ждем создания базы данных..."
sleep 3
if [ -f "$INSTALL_DIR/data/nexx.db" ]; then
    if command -v sqlite3 &> /dev/null; then
        sqlite3 "$INSTALL_DIR/data/nexx.db" "PRAGMA journal_mode=WAL;" >/dev/null 2>&1
        log_info "WAL режим включен"
    else
        log_warn "sqlite3 не установлен. apt install sqlite3"
    fi
fi

echo ""
echo -e "${CYAN}=========================================${NC}"
echo -e "${GREEN}Установка XNEXX завершена!${NC}"
echo -e "${CYAN}=========================================${NC}"
echo ""
echo "Server ID: $SERVER_ID"
echo "IP: $VPS_IP"
echo "Domain: $DOMAIN"
echo "Cert: $CERT_PATH"
echo "Mode: TLS + WebSocket"
echo ""
echo "Команды:"
echo "  systemctl status xnexx-agent"
echo "  journalctl -u xnexx-agent -f"
echo "  tail -f /var/log/sing-box.log"
echo ""
echo -e "${GREEN}Автообновление: каждый час${NC}"
echo -e "${GREEN}Certbot renewal: каждый день в 3:00${NC}"
echo -e "${CYAN}=========================================${NC}"