#!/bin/bash
# ========== configure_remnanode.sh ==========
# Настройка RemnaNode под panel.4rp.su
# Домен: ${LOCATION}.8rmdgz.ru
# Порт ноды: 9873
# Сокеты: /dev/shm/nginx.sock и /dev/shm/xrxh.socket,0666
# Токен: первая строка файла https://cloud.free-surf.ru/script/key в формате api_token=...

set -euo pipefail

# ────────────────────────────────────────────────
# ЛОГИРОВАНИЕ
# ────────────────────────────────────────────────
log_info()    { echo "ℹ️  [INFO]  $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_success() { echo "✅ [SUCCESS] $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_warning() { echo "⚠️  [WARNING] $(date '+%Y-%m-%d %H:%M:%S') - $1"; }
log_error()   { echo "❌ [ERROR]  $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2; }
log_step()    { echo ""; echo "📋 [STEP] $(date '+%Y-%m-%d %H:%M:%S') - $1"; echo "=================================================="; }

# ────────────────────────────────────────────────
# ПРОВЕРКИ
# ────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && { log_error "Скрипт должен запускаться от root"; exit 1; }
[[ -z "${LOCATION:-}" ]] && { log_error "Переменная LOCATION не установлена"; exit 1; }

log_info "Локация: $LOCATION"
log_info "Домен: ${LOCATION}.8rmdgz.ru"
log_info "Порт ноды: 9873"

# ────────────────────────────────────────────────
# jq
# ────────────────────────────────────────────────
if ! command -v jq &>/dev/null; then
    log_warning "jq не найден → установка..."
    if command -v apt &>/dev/null; then
        apt update -qq && apt install -y -qq jq
    elif command -v dnf &>/dev/null; then
        dnf install -y -q jq
    else
        log_error "Не удалось установить jq"
        exit 1
    fi
    log_success "jq установлен"
fi

# ────────────────────────────────────────────────
# API ТОКЕН — ЧТЕНИЕ ПЕРВОЙ СТРОКИ api_token=...
# ────────────────────────────────────────────────
log_step "Загрузка API-ключей"

KEYS_URL="https://cloud.free-surf.ru/script/key"
KEYS_FILE=$(mktemp --suffix=.keys)

if ! curl -fsSL --connect-timeout 12 "$KEYS_URL" -o "$KEYS_FILE"; then
    log_error "Не удалось скачать файл ключей: $KEYS_URL"
    rm -f "$KEYS_FILE"
    exit 1
fi

raw_line=$(head -n 1 "$KEYS_FILE")
API_TOKEN=$(echo "$raw_line" | sed -n 's/^api_token=//p' | tr -d ' \t\r\n' | head -1)

rm -f "$KEYS_FILE"

if [[ -z "$API_TOKEN" ]]; then
    log_error "Не удалось извлечь токен из первой строки"
    log_error "Полученная строка: '$raw_line'"
    exit 1
fi

log_success "API-токен загружен (первые 20 символов: ${API_TOKEN:0:20}...)"

# ────────────────────────────────────────────────
# ПРОВЕРКА ТОКЕНА
# ────────────────────────────────────────────────
API_URL="https://panel.4rp.su/api"
TEST_URL="${API_URL}/config-profiles"

log_step "Проверка токена"

response=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer $API_TOKEN" "$TEST_URL")
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [[ "$http_code" != "200" ]]; then
    log_error "Токен недействителен или API недоступно (HTTP $http_code)"
    [[ -n "$body" ]] && echo "Ответ API: $body"
    exit 1
fi
log_success "Токен валиден"

# ────────────────────────────────────────────────
# КОНФИГ ПРОФИЛЯ
# ────────────────────────────────────────────────
log_step "Подготовка конфигурации профиля"

PROFILE_NAME=$(echo "$LOCATION" | tr '[:lower:]' '[:upper:]')

CONFIG_TEMPLATE=$(cat <<'EOF'
{
  "log": { "loglevel": "info" },
  "dns": {
    "port": 53,
    "servers": ["tcp://127.0.0.1"],
    "queryStrategy": "UseIPv4"
  },
  "inbounds": [
    {
      "tag": "__LOCATION___vless_tcp",
      "port": 443,
      "protocol": "vless",
      "settings": { "clients": [], "decryption": "none" },
      "sniffing": { "enabled": true, "destOverride": ["http","tls","quic"] },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "dest": "/dev/shm/nginx.sock",
          "show": false,
          "xver": 1,
          "spiderX": "",
          "shortIds": ["63d3b84b13b62543"],
          "privateKey": "bYe9ICeNkZllf3aJDo4HMzYevFygROrRxabMLdyLl5c",
          "serverNames": ["__LOCATION__.8rmdgz.ru"]
        }
      }
    },
    {
      "tag": "__LOCATION___vless_xhttp",
      "listen": "/dev/shm/xrxh.socket,0666",
      "protocol": "vless",
      "settings": { "clients": [], "fallbacks": [], "decryption": "none" },
      "sniffing": { "enabled": true, "destOverride": ["http","tls","quic"] },
      "streamSettings": {
        "network": "xhttp",
        "xhttpSettings": {
          "mode": "auto",
          "path": "/xhttp/",
          "extra": {
            "noSSEHeader": true,
            "xPaddingBytes": "100-1000",
            "scMaxBufferedPosts": 30,
            "scMaxEachPostBytes": 1000000,
            "scStreamUpServerSecs": "20-80"
          }
        }
      }
    }
  ],
  "outbounds": [
    { "tag": "DIRECT", "protocol": "freedom" },
    { "tag": "BLOCK", "protocol": "blackhole" }
  ],
  "routing": {
    "rules": [
      { "ip": ["geoip:private"], "type": "field", "outboundTag": "BLOCK" },
      { "type": "field", "protocol": ["bittorrent"], "outboundTag": "BLOCK" }
    ]
  }
}
EOF
)

FINAL_JSON=$(echo "$CONFIG_TEMPLATE" | sed "s/__LOCATION__/$LOCATION/g")
if ! echo "$FINAL_JSON" | jq . >/dev/null 2>&1; then
    log_error "Ошибка формирования JSON профиля"
    echo "$FINAL_JSON" | head -20
    exit 1
fi

# ────────────────────────────────────────────────
# ПРОФИЛЬ
# ────────────────────────────────────────────────
log_step "Создание / получение профиля"

PROFILE_URL="${API_URL}/config-profiles"
CREATE_JSON=$(jq -n --arg name "$PROFILE_NAME" --argjson config "$FINAL_JSON" '{name: $name, config: $config}')

response=$(curl -s -w "\n%{http_code}" -X POST "$PROFILE_URL" \
    -H "Authorization: Bearer $API_TOKEN" \
    -H "Content-Type: application/json" \
    -d "$CREATE_JSON")

http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [[ $http_code == 201 ]]; then
    PROFILE_UUID=$(echo "$body" | jq -r '.response.uuid // .uuid // ""')
    INBOUNDS_JSON=$(echo "$body" | jq -c '.response.inbounds // .inbounds // []')
    log_success "Профиль создан"
elif [[ $http_code == 409 ]]; then
    log_warning "Профиль уже существует"
    
    response=$(curl -s -w "\n%{http_code}" -X GET "$PROFILE_URL" -H "Authorization: Bearer $API_TOKEN")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    [[ $http_code != 200 ]] && { log_error "Не удалось получить список профилей (HTTP $http_code)"; exit 1; }
    
    PROFILE_UUID=$(echo "$body" | jq -r --arg n "$PROFILE_NAME" '.response.configProfiles[]? | select(.name==$n) | .uuid // ""')
    [[ -z "$PROFILE_UUID" ]] && { log_error "Не удалось найти UUID профиля с именем $PROFILE_NAME"; exit 1; }
    
    profile_response=$(curl -s -w "\n%{http_code}" -X GET "${PROFILE_URL}/${PROFILE_UUID}" -H "Authorization: Bearer $API_TOKEN")
    profile_http_code=$(echo "$profile_response" | tail -n1)
    profile_body=$(echo "$profile_response" | sed '$d')
    
    [[ $profile_http_code != 200 ]] && { log_error "Не удалось получить детали профиля (HTTP $profile_http_code)"; exit 1; }
    
    INBOUNDS_JSON=$(echo "$profile_body" | jq -c '.response.inbounds // []')
    log_success "UUID профиля: $PROFILE_UUID"
else
    log_error "Ошибка профиля (HTTP $http_code)"
    echo "$body" | jq . 2>/dev/null || echo "$body"
    exit 1
fi

# ────────────────────────────────────────────────
# IP и страна
# ────────────────────────────────────────────────
SERVER_IP=$(curl -s --connect-timeout 8 ifconfig.me 2>/dev/null || hostname -I 2>/dev/null | awk '{print $1}' || echo "")
[[ -z "$SERVER_IP" ]] && { log_error "Не удалось определить IP"; exit 1; }

COUNTRY_DATA=$(curl -s --connect-timeout 8 "http://ip-api.com/json/$SERVER_IP?fields=country,countryCode")
COUNTRY_CODE=$(echo "$COUNTRY_DATA" | jq -r '.countryCode // "XX"')
COUNTRY_NAME=$(echo "$COUNTRY_DATA" | jq -r '.country // ""')

# ────────────────────────────────────────────────
# UUID ИНБАУНДОВ
# ────────────────────────────────────────────────
log_step "Поиск UUID инбаундов"

if [[ -z "$INBOUNDS_JSON" || "$INBOUNDS_JSON" == "null" ]]; then
    log_error "INBOUNDS_JSON пуст или null"
    exit 1
fi

REALITY_UUID=$(echo "$INBOUNDS_JSON" | jq -r '.[] | select(.tag | endswith("_vless_tcp")) | .uuid // ""')
XHTTP_UUID=$(echo "$INBOUNDS_JSON" | jq -r '.[] | select(.tag | endswith("_vless_xhttp")) | .uuid // ""')

if [[ -z "$REALITY_UUID" || -z "$XHTTP_UUID" ]]; then
    log_error "Не найдены UUID инбаундов"
    log_error "Reality: $REALITY_UUID, XHTTP: $XHTTP_UUID"
    echo "Доступные инбаунды:"
    echo "$INBOUNDS_JSON" | jq -r '.[] | "\(.tag): \(.uuid)"'
    exit 1
fi

# ────────────────────────────────────────────────
# ПРОВЕРКА СУЩЕСТВОВАНИЯ НОДЫ
# ────────────────────────────────────────────────
log_step "Проверка существования ноды"

NODE_NAME="${LOCATION}.8rmdgz.ru"
NODE_PORT=9873

# Получаем список всех нод
nodes_response=$(curl -s -w "\n%{http_code}" -X GET "${API_URL}/nodes" \
    -H "Authorization: Bearer $API_TOKEN")

nodes_http_code=$(echo "$nodes_response" | tail -n1)
nodes_body=$(echo "$nodes_response" | sed '$d')

if [[ $nodes_http_code != 200 ]]; then
    log_error "Не удалось получить список нод (HTTP $nodes_http_code)"
    exit 1
fi

# Ищем ноду с таким именем
EXISTING_NODE_UUID=$(echo "$nodes_body" | jq -r --arg name "$NODE_NAME" '.response[]? | select(.name==$name) | .uuid // ""' 2>/dev/null)

if [[ -n "$EXISTING_NODE_UUID" && "$EXISTING_NODE_UUID" != "null" ]]; then
    log_warning "Нода с именем $NODE_NAME уже существует (UUID: $EXISTING_NODE_UUID)"
    NODE_UUID="$EXISTING_NODE_UUID"
    NODE_SECRET_KEY="(недоступен через API)"
    NODE_CREATED="false"
else
    NODE_CREATED="true"
fi

# ────────────────────────────────────────────────
# СОЗДАНИЕ НОДЫ (если не существует)
# ────────────────────────────────────────────────
if [[ "$NODE_CREATED" == "true" ]]; then
    log_step "Создание новой ноды"

    INBOUND_ARRAY=$(echo "$INBOUNDS_JSON" | jq -r '[.[].uuid]')

    NODE_JSON=$(jq -n \
        --arg name "$NODE_NAME" \
        --arg addr "$SERVER_IP" \
        --argjson port "$NODE_PORT" \
        --arg puuid "$PROFILE_UUID" \
        --argjson inbs "$INBOUND_ARRAY" \
        --arg cc "${COUNTRY_CODE:-XX}" \
        '{
            name: $name,
            address: $addr,
            port: $port,
            countryCode: $cc,
            configProfile: { activeConfigProfileUuid: $puuid, activeInbounds: $inbs },
            isTrafficTrackingActive: false,
            consumptionMultiplier: 1.0
        }')

    log_info "Отправляемый JSON для создания ноды:"
    echo "$NODE_JSON" | jq -c .

    response=$(curl -s -w "\n%{http_code}" -X POST "${API_URL}/nodes" \
        -H "Authorization: Bearer $API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$NODE_JSON")

    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')

    if [[ $http_code != 201 && $http_code != 200 ]]; then
        log_error "Ошибка создания ноды (HTTP $http_code)"
        echo "$body" | jq . 2>/dev/null || echo "$body"
        exit 1
    fi

    # Извлекаем UUID ноды из ответа
    NODE_UUID=$(echo "$body" | jq -r '.response.uuid // .uuid // ""' 2>/dev/null)

    if [[ -z "$NODE_UUID" || "$NODE_UUID" == "null" ]]; then
        log_error "Не удалось извлечь UUID ноды из ответа"
        exit 1
    fi

    log_success "Нода создана: $NODE_NAME ($NODE_UUID)"
    
    # Информируем пользователя о секретном ключе
    log_warning "Секретный ключ ноды не возвращается через API Remnawave."
    log_warning "Он будет сгенерирован автоматически при первом запуске ноды."
    log_warning "Убедитесь, что нода может连接到 панели для получения ключа."
    
    NODE_SECRET_KEY="(генерируется при первом запуске ноды)"
fi

# ────────────────────────────────────────────────
# РЕМАРКИ + ФЛАГ
# ────────────────────────────────────────────────
FLAG=""
if [[ ${#COUNTRY_CODE} -eq 2 ]]; then
    first=$((0x1F1E6 + $(printf '%d' "'${COUNTRY_CODE:0:1}") - 65))
    second=$((0x1F1E6 + $(printf '%d' "'${COUNTRY_CODE:1:1}") - 65))
    
    if [[ $first -ge $((0x1F1E6)) && $first -le $((0x1F1FF)) && \
          $second -ge $((0x1F1E6)) && $second -le $((0x1F1FF)) ]]; then
        FLAG=$(printf "\\U$(printf '%x' $first)\\U$(printf '%x' $second)")
    else
        FLAG="🏳️"
    fi
else
    FLAG="🏳️"
fi

BASE_REMARK="${FLAG} ${COUNTRY_NAME:-$COUNTRY_CODE}${LOCATION//[^0-9]/}"

# ────────────────────────────────────────────────
# ХОСТ REALITY
# ────────────────────────────────────────────────
log_step "Создание Reality-хоста"

# Проверяем, существует ли уже такой хост
hosts_response=$(curl -s -w "\n%{http_code}" -X GET "${API_URL}/hosts" \
    -H "Authorization: Bearer $API_TOKEN")

hosts_http_code=$(echo "$hosts_response" | tail -n1)
hosts_body=$(echo "$hosts_response" | sed '$d')

EXISTING_REALITY_HOST=$(echo "$hosts_body" | jq -r --arg rem "${BASE_REMARK} Reality" '.response[]? | select(.remark==$rem) | .uuid // ""' 2>/dev/null)

if [[ -n "$EXISTING_REALITY_HOST" && "$EXISTING_REALITY_HOST" != "null" ]]; then
    log_warning "Reality хост с таким именем уже существует (UUID: $EXISTING_REALITY_HOST)"
else
    HOST_JSON_R=$(jq -n \
        --arg pu "$PROFILE_UUID" \
        --arg iu "$REALITY_UUID" \
        --arg rem "${BASE_REMARK} Reality" \
        --arg addr "$NODE_NAME" \
        --argjson p 443 \
        --arg sni "$NODE_NAME" \
        --arg nu "$NODE_UUID" \
        '{
            inbound: { configProfileUuid: $pu, configProfileInboundUuid: $iu },
            remark: $rem,
            address: $addr,
            port: $p,
            sni: $sni,
            nodes: [$nu],
            isDisabled: false
        }')

    response=$(curl -s -w "\n%{http_code}" -X POST "${API_URL}/hosts" \
        -H "Authorization: Bearer $API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$HOST_JSON_R")

    http_code=$(echo "$response" | tail -n1)
    [[ $http_code != 201 && $http_code != 200 ]] && { log_error "Ошибка Reality хоста (HTTP $http_code)"; exit 1; }
    log_success "Reality хост создан"
fi

# ────────────────────────────────────────────────
# ХОСТ XHTTP
# ────────────────────────────────────────────────
log_step "Создание xHTTP-хоста"

EXISTING_XHTTP_HOST=$(echo "$hosts_body" | jq -r --arg rem "${BASE_REMARK} xHTTP" '.response[]? | select(.remark==$rem) | .uuid // ""' 2>/dev/null)

if [[ -n "$EXISTING_XHTTP_HOST" && "$EXISTING_XHTTP_HOST" != "null" ]]; then
    log_warning "xHTTP хост с таким именем уже существует (UUID: $EXISTING_XHTTP_HOST)"
else
    XHTTP_EXTRA='{
      "xmux": {
        "cMaxReuseTimes": 0,
        "maxConcurrency": "16-32",
        "maxConnections": 0,
        "hKeepAlivePeriod": 0,
        "hMaxRequestTimes": "600-900",
        "hMaxReusableSecs": "1800-3000"
      },
      "noGRPCHeader": false,
      "xPaddingBytes": "100-1000",
      "scMaxBufferedPosts": 30,
      "scMaxEachPostBytes": 1000000,
      "scMinPostsIntervalMs": 30,
      "scStreamUpServerSecs": "20-80"
    }'

    HOST_JSON_X=$(jq -n \
        --arg pu "$PROFILE_UUID" \
        --arg iu "$XHTTP_UUID" \
        --arg rem "${BASE_REMARK} xHTTP" \
        --arg addr "$NODE_NAME" \
        --argjson p 443 \
        --arg path "/xhttp/" \
        --arg sni "$NODE_NAME" \
        --arg host "$NODE_NAME" \
        --argjson extra "$XHTTP_EXTRA" \
        --arg nu "$NODE_UUID" \
        '{
            inbound: { configProfileUuid: $pu, configProfileInboundUuid: $iu },
            remark: $rem,
            address: $addr,
            port: $p,
            path: $path,
            sni: $sni,
            host: $host,
            alpn: "h2,http/1.1",
            fingerprint: "chrome",
            securityLayer: "TLS",
            xHttpExtraParams: $extra,
            nodes: [$nu],
            isDisabled: false
        }')

    response=$(curl -s -w "\n%{http_code}" -X POST "${API_URL}/hosts" \
        -H "Authorization: Bearer $API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$HOST_JSON_X")

    http_code=$(echo "$response" | tail -n1)
    [[ $http_code != 201 && $http_code != 200 ]] && { log_error "Ошибка xHTTP хоста (HTTP $http_code)"; exit 1; }
    log_success "xHTTP хост создан"
fi

# ────────────────────────────────────────────────
# ФИНАЛ
# ────────────────────────────────────────────────
log_success "Настройка завершена успешно"
echo ""
echo "=================================================="
echo "Локация          : $LOCATION"
echo "Домен            : ${LOCATION}.8rmdgz.ru"
echo "Порт ноды        : 9873"
echo "Профиль          : $PROFILE_NAME"
echo "UUID профиля     : $PROFILE_UUID"
echo "UUID ноды        : $NODE_UUID"
echo "Secret Key       : $NODE_SECRET_KEY"
echo "IP сервера       : $SERVER_IP"
echo "Код страны       : $COUNTRY_CODE"
echo "Название страны  : $COUNTRY_NAME"
echo "=================================================="
echo ""

if [[ "$NODE_CREATED" == "true" ]]; then
    echo "⚠️  Секретный ключ будет сгенерирован автоматически при первом запуске ноды."
    echo "    Убедитесь, что нода может连接到 панели для получения ключа."
    echo ""
fi

exit 0
