#!/bin/sh
set -e

CLIENT_NAME="{{CLIENT_NAME}}"
PROTOCOL="{{PROTOCOL}}"
PHOBOS_DIR=""
ROUTER_PLATFORM=""
SLOT=""
LPORT=""

. "$(dirname "$0")/lib-client.sh"
. "$(dirname "$0")/install-obfuscator.sh"
. "$(dirname "$0")/install-wireguard.sh"

PHASE_TOTAL=3

phase_start() {
  msg ""
  msg "[${1}/${PHASE_TOTAL}] ${2}..."
}

phase_ok() {
  msg "[${1}/${PHASE_TOTAL}] ✓ ${2}"
}

phase_fail() {
  msg "[${1}/${PHASE_TOTAL}] ✗ ${2}"
}

detect_3xui_mode() {
  local platform="$1"
  [ "$platform" = "linux" ] || { echo "false"; return; }
  [ "$(detect_arch)" = "x86_64" ] || { echo "false"; return; }
  if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet x-ui 2>/dev/null; then
    echo "true"; return
  fi
  for _db in /etc/x-ui/x-ui.db /usr/local/x-ui/x-ui.db /opt/x-ui/x-ui.db; do
    [ -f "$_db" ] && { echo "true"; return; }
  done
  command -v x-ui >/dev/null 2>&1 && { echo "true"; return; }
  echo "false"
}

check_dependencies() {
  local platform="$1"
  local deps
  case "$platform" in
    keenetic) deps="grep cut date tar curl jq" ;;
    openwrt)  deps="grep cut date tar uci" ;;
    *)        deps="grep cut date tar" ;;
  esac
  local missing=""
  for cmd in $deps; do
    command -v "$cmd" >/dev/null 2>&1 || missing="$missing $cmd"
  done
  [ -z "$missing" ] && return 0
  if [ -z "$PKG_MGR" ]; then
    msg "ОШИБКА: отсутствуют утилиты:${missing} — установите вручную"
    return 1
  fi
  pkg_update >/dev/null 2>&1 || true
  for cmd in $missing; do
    pkg_install "$cmd" >/dev/null 2>&1 || true
  done
  return 0
}

setup_configs() {
  mkdir -p "$PHOBOS_DIR"
  cp wg-obfuscator.conf "$PHOBOS_DIR/${OBF_CONF_NAME}"
  chmod 600 "$PHOBOS_DIR/${OBF_CONF_NAME}"
  cp "${CLIENT_NAME}.conf" "$PHOBOS_DIR/${CLIENT_NAME}.conf"
  chmod 600 "$PHOBOS_DIR/${CLIENT_NAME}.conf"
  sed -i "s/^source-lport = .*/source-lport = ${LPORT}/" "$PHOBOS_DIR/${OBF_CONF_NAME}"
  sed -i "s/^Endpoint = 127\.0\.0\.1:.*/Endpoint = 127.0.0.1:${LPORT}/" "$PHOBOS_DIR/${CLIENT_NAME}.conf"
}

setup_configs_socks5() {
  mkdir -p "$PHOBOS_DIR"
  cp wg-socks5-obfuscator.conf "$PHOBOS_DIR/${OBF_CONF_NAME}"
  chmod 600 "$PHOBOS_DIR/${OBF_CONF_NAME}"
  sed -i "s/^source-lport = .*/source-lport = ${LPORT}/" "$PHOBOS_DIR/${OBF_CONF_NAME}"
}

allocate_slot() {
  local existing
  existing=$(registry_line_for_client "$CLIENT_NAME")
  if [ -n "$existing" ]; then
    SLOT=$(registry_field "$existing" 2)
    LPORT=$(registry_field "$existing" 3)
  else
    SLOT=$(registry_alloc_slot)
    LPORT=$(registry_alloc_port 13255)
  fi
  compute_slot_names "$SLOT"
}

register_client() {
  local target masking iface_ref
  target=$(grep '^target' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
  masking=$(grep '^masking' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
  if [ "$ROUTER_PLATFORM" = "keenetic" ]; then
    iface_ref="Phobos-${CLIENT_NAME}"
  else
    iface_ref="${OBF_WG_IFACE}"
  fi
  registry_remove_client "$CLIENT_NAME"
  registry_add "${CLIENT_NAME}|${SLOT}|${LPORT}|${OBF_CONF_NAME}|${OBF_BINARY_NAME}|${OBF_INIT_NAME}|${OBF_SERVICE_NAME}|${iface_ref}|${target}|${masking}|$(date '+%Y-%m-%d %H:%M:%S')"
}

deploy_lib_client() {
  [ -f "lib-client.sh" ] && cp "lib-client.sh" "$PHOBOS_DIR/lib-client.sh"
}

deploy_uninstall_script() {
  if [ -f "phobos-uninstall.sh" ]; then
    cp "phobos-uninstall.sh" "$PHOBOS_DIR/phobos-uninstall.sh"
    chmod +x "$PHOBOS_DIR/phobos-uninstall.sh"
  fi
}

verify_obfuscator_service() {
  [ -f "/etc/systemd/system/${OBF_SERVICE_NAME}.service" ] || return 1
  systemctl is-enabled --quiet "${OBF_SERVICE_NAME}" 2>/dev/null || return 1
  systemctl is-active --quiet "${OBF_SERVICE_NAME}" 2>/dev/null || return 1
}

_json_str_array() {
  local raw="$1" indent="$2"
  local result="" item first=1 _ifs
  _ifs="$IFS"
  IFS=','
  for item in $raw; do
    IFS="$_ifs"
    item=$(printf '%s' "$item" | tr -d ' \t')
    if [ -n "$item" ]; then
      if [ "$first" = "1" ]; then
        result="${indent}\"${item}\""; first=0
      else
        result="${result},
${indent}\"${item}\""
      fi
    fi
    IFS=','
  done
  IFS="$_ifs"
  printf '%s' "$result"
}

print_xray_wireguard_json() {
  local conf="${PHOBOS_DIR}/${CLIENT_NAME}.conf"
  local secret_key mtu public_key preshared_key keepalive raw_addr raw_allowed

  secret_key=$(  grep '^PrivateKey'                        "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
  mtu=$(         grep '^MTU'                               "$conf" | head -1 | cut -d'=' -f2  | tr -d ' \t\r\n')
  public_key=$(  grep '^PublicKey'                         "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
  preshared_key=$(grep -E '^PresharedKey|^PreSharedKey'   "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
  keepalive=$(   grep '^PersistentKeepalive'               "$conf" | head -1 | cut -d'=' -f2  | tr -d ' \t\r\n')
  raw_addr=$(    grep '^Address'                           "$conf" | head -1 | cut -d'=' -f2- | tr -d '\t\r\n')
  raw_allowed=$( grep '^AllowedIPs'                        "$conf" | head -1 | cut -d'=' -f2- | tr -d '\t\r\n')

  [ -z "$mtu"       ] && mtu=1420
  [ -z "$keepalive" ] && keepalive=0

  local addr_arr allowed_arr
  addr_arr=$(    _json_str_array "$raw_addr"     "      ")
  allowed_arr=$( _json_str_array "$raw_allowed"  "          ")

  printf '{
  "protocol": "wireguard",
  "settings": {
    "mtu": %s,
    "secretKey": "%s",
    "address": [
%s
    ],
    "workers": 2,
    "peers": [
      {
        "publicKey": "%s",
        "preSharedKey": "%s",
        "allowedIPs": [
%s
        ],
        "endpoint": "127.0.0.1:%s",
        "keepAlive": %s
      }
    ],
    "noKernelTun": false
  },
  "tag": "Phobos-%s"
}
' "$mtu" "$secret_key" "$addr_arr" \
  "$public_key" "$preshared_key" "$allowed_arr" \
  "$LPORT" "$keepalive" "$CLIENT_NAME"
}

print_xray_socks5_json() {
  printf '{
  "protocol": "socks",
  "settings": {
    "servers": [
      {
        "address": "127.0.0.1",
        "port": %s,
        "users": [
          {
            "user": "%s",
            "pass": "%s"
          }
        ]
      }
    ]
  },
  "tag": "Phobos-%s"
}
' "$LPORT" "$SOCKS5_LOGIN" "$SOCKS5_PASSWORD" "$CLIENT_NAME"
}

extract_wireguard_params() {
  local config_file="$PHOBOS_DIR/${CLIENT_NAME}.conf"

  WG_PRIVATE_KEY=$(grep '^PrivateKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
  WG_ADDRESS=$(grep '^Address' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
  WG_SERVER_PUBKEY=$(grep '^PublicKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
  WG_PRESHARED_KEY=$(
    grep -E '^PresharedKey|^PreSharedKey' "$config_file" |
      head -1 |
      cut -d'=' -f2- |
      tr -d ' \t\n\r'
  )
  WG_ENDPOINT_PORT=$(grep '^Endpoint' "$config_file" | cut -d':' -f2 | tr -d ' \t\n\r')

  CLIENT_IP=$(echo "$WG_ADDRESS" | cut -d',' -f1 | tr -d ' ')
  CLIENT_IPV6=$(echo "$WG_ADDRESS" | cut -d',' -f2 | tr -d ' ')

  if [ -z "$CLIENT_IPV6" ] || [ "$CLIENT_IPV6" = "$CLIENT_IP" ]; then
    CLIENT_IPV6=$(grep -A 10 '\[Interface\]' "$config_file" | grep '^Address' | grep -o 'fd[0-9a-f:\/]*' | head -1)
  fi
  [ -z "$CLIENT_IPV6" ] && CLIENT_IPV6="none"
  [ -z "$WG_ENDPOINT_PORT" ] && WG_ENDPOINT_PORT=13255

  if [ -z "$WG_PRESHARED_KEY" ]; then
    msg "  PrivateKey:   $(printf '%s' "$WG_PRIVATE_KEY"   | cut -c1-20)..."
    msg "  Address:      $WG_ADDRESS"
    msg "  PublicKey:    $(printf '%s' "$WG_SERVER_PUBKEY" | cut -c1-20)..."
    msg "  EndpointPort: $WG_ENDPOINT_PORT"
    msg "ОШИБКА: PresharedKey не найден в ${config_file}"
    return 1
  fi
}

install_wireguard_openwrt() {
  command -v wg >/dev/null 2>&1 && return 0
  pkg_update >/dev/null 2>&1 || true
  pkg_install kmod-wireguard wireguard-tools luci-proto-wireguard >/dev/null 2>&1
}

install_redsocks_openwrt() {
  if [ -x /usr/sbin/redsocks ] || command -v redsocks >/dev/null 2>&1; then
    return 0
  fi
  pkg_update >/dev/null 2>&1 || true
  pkg_install redsocks >/dev/null 2>&1 || true
  [ -x /usr/sbin/redsocks ] || command -v redsocks >/dev/null 2>&1
}

configure_wireguard_rci() {
  extract_wireguard_params || return 1
  [ -f "./router-configure-wireguard.sh" ] || return 1
  chmod +x ./router-configure-wireguard.sh
  local _log="${PHOBOS_DIR}/.rci.log"
  if ./router-configure-wireguard.sh \
      --client-name "$CLIENT_NAME" \
      --client-private-key "$WG_PRIVATE_KEY" \
      --client-ip "$CLIENT_IP" \
      --client-ipv6 "$CLIENT_IPV6" \
      --server-public-key "$WG_SERVER_PUBKEY" \
      --preshared-key "$WG_PRESHARED_KEY" \
      --endpoint-port "$WG_ENDPOINT_PORT" \
      --keepalive 25 \
      --mtu 1420 \
      --fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf" >"$_log" 2>&1; then
    rm -f "$_log"
    return 0
  fi
  cat "$_log" 2>/dev/null || true
  rm -f "$_log"
  return 1
}

load_socks5_credentials() {
  [ -f "socks5-credentials.env" ] || return 1
  . ./socks5-credentials.env
  [ -n "$SOCKS5_LOGIN" ] && [ -n "$SOCKS5_PASSWORD" ]
}

configure_socks5_rci() {
  load_socks5_credentials || return 1
  [ -f "./router-configure-socks5-keenetic.sh" ] || return 1
  chmod +x ./router-configure-socks5-keenetic.sh
  local _log="${PHOBOS_DIR}/.rci.log"
  if ./router-configure-socks5-keenetic.sh \
      --client-name "$CLIENT_NAME" \
      --upstream-host "127.0.0.1" \
      --upstream-port "$LPORT" \
      --login "$SOCKS5_LOGIN" \
      --password "$SOCKS5_PASSWORD" \
      --fallback-config "$PHOBOS_DIR/${OBF_CONF_NAME}" >"$_log" 2>&1; then
    rm -f "$_log"
    return 0
  fi
  cat "$_log" 2>/dev/null || true
  rm -f "$_log"
  return 1
}

configure_socks5_openwrt() {
  load_socks5_credentials || return 1
  [ -f "./router-configure-socks5-openwrt.sh" ] || return 1
  chmod +x ./router-configure-socks5-openwrt.sh
  local target server_ip
  target=$(grep '^target' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
  server_ip="${target%:*}"
  local _log="${PHOBOS_DIR}/.uci.log"
  if ./router-configure-socks5-openwrt.sh \
      --client-name "$CLIENT_NAME" \
      --obf-port "$LPORT" \
      --login "$SOCKS5_LOGIN" \
      --password "$SOCKS5_PASSWORD" \
      --server-ip "$server_ip" >"$_log" 2>&1; then
    rm -f "$_log"
    return 0
  fi
  cat "$_log" 2>/dev/null || true
  rm -f "$_log"
  return 1
}

configure_wireguard_openwrt() {
  extract_wireguard_params || return 1
  [ -f "./router-configure-wireguard-openwrt.sh" ] || return 1
  chmod +x ./router-configure-wireguard-openwrt.sh
  local _log="${PHOBOS_DIR}/.uci.log"
  if ./router-configure-wireguard-openwrt.sh \
      --client-name "$CLIENT_NAME" \
      --interface "$OBF_WG_IFACE" \
      --client-private-key "$WG_PRIVATE_KEY" \
      --client-ip "$CLIENT_IP" \
      --client-ipv6 "$CLIENT_IPV6" \
      --server-public-key "$WG_SERVER_PUBKEY" \
      --preshared-key "$WG_PRESHARED_KEY" \
      --endpoint-port "$WG_ENDPOINT_PORT" \
      --keepalive 25 \
      --mtu 1420 \
      --fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf" >"$_log" 2>&1; then
    rm -f "$_log"
    return 0
  fi
  cat "$_log" 2>/dev/null || true
  rm -f "$_log"
  return 1
}

show_3xui_final_info() {
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${CLIENT_NAME}.conf         — конфигурация WireGuard клиента"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/usr/local/bin/${OBF_BINARY_NAME}"
  msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
  msg ""
  msg "Управление:"
  msg "  systemctl status ${OBF_SERVICE_NAME}"
  msg "  systemctl restart ${OBF_SERVICE_NAME}"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  msg ""
  msg "─────────────────────────────────────────────────"
  msg "WireGuard outbound для 3x-ui (добавить вручную):"
  msg "─────────────────────────────────────────────────"
  print_xray_wireguard_json
  msg "─────────────────────────────────────────────────"
}

show_3xui_socks5_final_info() {
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора SOCKS5 (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/usr/local/bin/${OBF_BINARY_NAME}"
  msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
  msg ""
  msg "Управление:"
  msg "  systemctl status ${OBF_SERVICE_NAME}"
  msg "  systemctl restart ${OBF_SERVICE_NAME}"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  msg ""
  msg "Локальный SOCKS5-прокси: 127.0.0.1:${LPORT}  (логин ${SOCKS5_LOGIN} / пароль ${SOCKS5_PASSWORD})"
  msg ""
  msg "─────────────────────────────────────────────────"
  msg "SOCKS outbound для 3x-ui (добавить вручную):"
  msg "─────────────────────────────────────────────────"
  print_xray_socks5_json
  msg "─────────────────────────────────────────────────"
}

show_keenetic_final_info() {
  local rci_ok="$1"
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${CLIENT_NAME}.conf         — конфигурация WireGuard клиента"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/opt/bin/${OBF_BINARY_NAME}"
  msg "/opt/etc/init.d/${OBF_INIT_NAME}"
  msg ""
  msg "Управление:"
  msg "  /opt/etc/init.d/${OBF_INIT_NAME} status"
  msg "  /opt/etc/init.d/${OBF_INIT_NAME} restart"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  if [ "$rci_ok" != "1" ]; then
    msg ""
    msg "Ручная настройка WireGuard (Keenetic):"
    msg "  1. Веб-панель → Интернет → Другие подключения"
    msg "  2. WireGuard → Загрузить конфигурацию из файла"
    msg "  3. Файл: ${PHOBOS_DIR}/${CLIENT_NAME}.conf"
    msg "  4. Активируйте подключение"
  fi
}

show_keenetic_socks5_final_info() {
  local rci_ok="$1"
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/opt/bin/${OBF_BINARY_NAME}"
  msg "/opt/etc/init.d/${OBF_INIT_NAME}"
  msg ""
  msg "Управление:"
  msg "  /opt/etc/init.d/${OBF_INIT_NAME} status"
  msg "  /opt/etc/init.d/${OBF_INIT_NAME} restart"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  if [ "$rci_ok" != "1" ]; then
    msg ""
    msg "Ручная настройка SOCKS5 Proxy (Keenetic):"
    msg "  1. Веб-панель → Интернет → Другие подключения → Добавить подключение"
    msg "  2. Тип: Proxy, протокол SOCKS5"
    msg "  3. Upstream: 127.0.0.1:${LPORT}"
    msg "  4. Логин/пароль — см. страницу клиента в панели PhobosWG"
    msg "  5. Активируйте подключение"
  fi
}

show_openwrt_final_info() {
  local uci_ok="$1"
  local init_path="$2"
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${CLIENT_NAME}.conf         — конфигурация WireGuard клиента"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/usr/bin/${OBF_BINARY_NAME}"
  msg "${init_path}"
  msg ""
  msg "Управление:"
  msg "  ${init_path} status"
  msg "  ${init_path} restart"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  if [ "$uci_ok" != "1" ]; then
    msg ""
    msg "Ручная настройка WireGuard (OpenWRT):"
    msg "  1. LuCI → Network → Interfaces → Add new"
    msg "  2. Протокол: WireGuard VPN"
    msg "  3. Параметры из файла: ${PHOBOS_DIR}/${CLIENT_NAME}.conf"
    msg "  4. Настройте firewall zone"
  fi
}

show_openwrt_socks5_final_info() {
  local ok="$1"
  local init_path="$2"
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора SOCKS5 (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/usr/bin/${OBF_BINARY_NAME}"
  msg "${init_path}"
  msg "/etc/redsocks.conf                       — транспарентный SOCKS5-редирект"
  msg "/etc/nftables.d/30-phobos-socks5.nft     — правило редиректа (fw4)"
  msg ""
  msg "Управление:"
  msg "  ${init_path} status"
  msg "  /etc/init.d/redsocks status"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
  if [ "$ok" = "1" ]; then
    msg ""
    msg "TCP-трафик из LAN прозрачно идёт через SOCKS5 → сервер."
  else
    msg ""
    msg "Ручная настройка SOCKS5 (OpenWRT):"
    msg "  1. Установите redsocks (${PKG_MGR} install redsocks)"
    msg "  2. /etc/redsocks.conf → upstream 127.0.0.1:${LPORT}, type socks5, login/пароль клиента"
    msg "  3. nft redirect для LAN TCP → порт redsocks (см. router-configure-socks5-openwrt.sh)"
  fi
}

show_linux_final_info() {
  msg ""
  msg "Файлы:"
  msg "${PHOBOS_DIR}/"
  msg "├─ ${CLIENT_NAME}.conf         — конфигурация WireGuard клиента"
  msg "├─ ${OBF_CONF_NAME}  — конфигурация обфускатора (порт ${LPORT})"
  msg "└─ phobos-uninstall.sh        — скрипт удаления PhobosWG"
  msg ""
  msg "/usr/local/bin/${OBF_BINARY_NAME}"
  msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
  msg "/etc/wireguard/${OBF_WG_IFACE}.conf"
  msg ""
  msg "Управление:"
  msg "  systemctl status ${OBF_SERVICE_NAME}"
  msg "  systemctl status wg-quick@${OBF_WG_IFACE}"
  msg "  ${PHOBOS_DIR}/phobos-uninstall.sh"
}

_run_3xui() {
  PHASE_TOTAL=3

  phase_start 1 "Установка службы обфускатора"
  install_obfuscator "$ARCH"
  setup_configs
  if create_systemd_obfuscator_service; then
    phase_ok 1 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 1 "служба создана, но не запустилась (таймаут 10 сек)"
  fi

  phase_start 2 "Проверка ${OBF_SERVICE_NAME}"
  if verify_obfuscator_service; then
    phase_ok 2 "служба установлена, включена и запущена"
  else
    phase_fail 2 "служба не полностью активирована — systemctl status ${OBF_SERVICE_NAME}"
  fi

  phase_start 3 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"

  show_3xui_final_info
}

_run_3xui_socks5() {
  PHASE_TOTAL=3

  load_socks5_credentials || true

  phase_start 1 "Установка службы обфускатора SOCKS5"
  install_obfuscator "$ARCH"
  setup_configs_socks5
  if create_systemd_obfuscator_service; then
    phase_ok 1 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 1 "служба создана, но не запустилась (таймаут 10 сек)"
  fi

  phase_start 2 "Проверка ${OBF_SERVICE_NAME}"
  if verify_obfuscator_service; then
    phase_ok 2 "служба установлена, включена и запущена"
  else
    phase_fail 2 "служба не полностью активирована — systemctl status ${OBF_SERVICE_NAME}"
  fi

  phase_start 3 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"

  show_3xui_socks5_final_info
}

_run_keenetic() {
  PHASE_TOTAL=3
  local rci_ok=0

  phase_start 1 "Установка обфускатора"
  install_obfuscator "$ARCH"
  setup_configs
  create_init_script
  if start_obfuscator; then
    phase_ok 1 "wg-obfuscator запущен → /opt/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 1 "wg-obfuscator не запущен — /opt/etc/init.d/${OBF_INIT_NAME} status"
  fi

  phase_start 2 "Настройка WireGuard (RCI API)"
  if configure_wireguard_rci; then
    rci_ok=1
    phase_ok 2 "интерфейс Phobos-${CLIENT_NAME} создан"
  else
    phase_fail 2 "WireGuard не настроен — потребуется ручная конфигурация"
  fi

  phase_start 3 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"

  show_keenetic_final_info "$rci_ok"
}

_run_keenetic_socks5() {
  PHASE_TOTAL=3
  local rci_ok=0

  phase_start 1 "Установка обфускатора"
  install_obfuscator "$ARCH"
  setup_configs_socks5
  create_init_script
  if start_obfuscator; then
    phase_ok 1 "wg-obfuscator запущен → /opt/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 1 "wg-obfuscator не запущен — /opt/etc/init.d/${OBF_INIT_NAME} status"
  fi

  phase_start 2 "Настройка SOCKS5 Proxy (RCI API)"
  if configure_socks5_rci; then
    rci_ok=1
    phase_ok 2 "интерфейс Phobos-${CLIENT_NAME} создан"
  else
    phase_fail 2 "SOCKS5 Proxy не настроен — потребуется ручная конфигурация"
  fi

  phase_start 3 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"

  show_keenetic_socks5_final_info "$rci_ok"
}

_run_openwrt() {
  PHASE_TOTAL=4
  local uci_ok=0
  local init_path=""

  phase_start 1 "Установка пакетов WireGuard"
  if install_wireguard_openwrt; then
    phase_ok 1 "kmod-wireguard + wireguard-tools"
  else
    phase_fail 1 "не удалось установить пакеты WireGuard"
  fi

  phase_start 2 "Установка обфускатора"
  install_obfuscator "$ARCH"
  setup_configs
  if [ -d "/opt/etc" ]; then
    create_init_script
    init_path="/opt/etc/init.d/${OBF_INIT_NAME}"
  else
    create_procd_init_script
    init_path="/etc/init.d/${OBF_SERVICE_NAME}"
  fi
  if start_obfuscator; then
    phase_ok 2 "wg-obfuscator запущен → /usr/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 2 "wg-obfuscator не запущен — ${init_path} status"
  fi

  phase_start 3 "Настройка WireGuard (UCI)"
  if configure_wireguard_openwrt; then
    uci_ok=1
    phase_ok 3 "интерфейс ${OBF_WG_IFACE} создан"
  else
    phase_fail 3 "WireGuard не настроен — потребуется ручная конфигурация"
  fi

  phase_start 4 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"

  show_openwrt_final_info "$uci_ok" "$init_path"
}

_run_openwrt_socks5() {
  PHASE_TOTAL=4
  local proxy_ok=0
  local init_path=""

  phase_start 1 "Установка redsocks"
  if install_redsocks_openwrt; then
    phase_ok 1 "redsocks установлен"
  else
    phase_fail 1 "не удалось установить redsocks — потребуется ручная настройка"
  fi

  phase_start 2 "Установка обфускатора"
  install_obfuscator "$ARCH"
  setup_configs_socks5
  if [ -d "/opt/etc" ]; then
    create_init_script
    init_path="/opt/etc/init.d/${OBF_INIT_NAME}"
  else
    create_procd_init_script
    init_path="/etc/init.d/${OBF_SERVICE_NAME}"
  fi
  if start_obfuscator; then
    phase_ok 2 "wg-obfuscator запущен → /usr/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 2 "wg-obfuscator не запущен — ${init_path} status"
  fi

  phase_start 3 "Настройка SOCKS5 (redsocks + nft redirect)"
  if configure_socks5_openwrt; then
    proxy_ok=1
    phase_ok 3 "транспарентный SOCKS5-редирект активен"
  else
    phase_fail 3 "SOCKS5 не настроен — потребуется ручная конфигурация"
  fi

  phase_start 4 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"

  show_openwrt_socks5_final_info "$proxy_ok" "$init_path"
}

_run_linux() {
  PHASE_TOTAL=4

  phase_start 1 "Установка WireGuard"
  if install_wireguard_linux; then
    phase_ok 1 "WireGuard установлен"
  else
    msg "ОШИБКА: не удалось установить WireGuard"
    exit 1
  fi

  phase_start 2 "Установка обфускатора"
  install_obfuscator "$ARCH"
  setup_configs
  if create_systemd_obfuscator_service; then
    phase_ok 2 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
  else
    phase_fail 2 "служба создана, но не запустилась (таймаут 10 сек)"
  fi

  phase_start 3 "Настройка WireGuard"
  if configure_wireguard_linux; then
    configure_ufw_linux
    phase_ok 3 "интерфейс ${OBF_WG_IFACE} настроен через systemd"
  else
    phase_fail 3 "WireGuard настроен с предупреждениями — systemctl status wg-quick@${OBF_WG_IFACE}"
  fi

  phase_start 4 "Сохранение файлов"
  register_client
  deploy_lib_client
  deploy_uninstall_script
  phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"

  show_linux_final_info
}

main() {
  ROUTER_PLATFORM=$(detect_router_platform)
  PHOBOS_DIR=$(detect_phobos_dir "$ROUTER_PLATFORM")
  IS_3XUI_MODE=$(detect_3xui_mode "$ROUTER_PLATFORM")
  detect_pkg_manager

  if [ "$ROUTER_PLATFORM" = "unknown" ]; then
    msg "ОШИБКА: Неподдерживаемая платформа ($(uname -a))"
    msg "Поддерживаются: Keenetic, OpenWRT, Linux (Ubuntu/Debian)"
    exit 1
  fi

  if [ "$PROTOCOL" = "socks5" ] && [ "$ROUTER_PLATFORM" != "keenetic" ] && \
     [ "$ROUTER_PLATFORM" != "openwrt" ] && [ "$IS_3XUI_MODE" != "true" ]; then
    msg "Автоматическая установка SOCKS5 для платформы ${ROUTER_PLATFORM} пока не поддерживается."
    msg "Используйте wg-socks5-obfuscator.conf и бинарник из bin/ вручную (см. README.txt)."
    exit 0
  fi

  check_root
  mkdir -p "$PHOBOS_DIR"
  allocate_slot

  ARCH=$(detect_arch)
  if [ "$ARCH" = "unknown" ]; then
    msg "ОШИБКА: Неподдерживаемая архитектура ($(uname -m))"
    exit 1
  fi

  if [ "$IS_3XUI_MODE" = "true" ]; then
    MODE_LABEL="3x-ui"
  elif [ "$ROUTER_PLATFORM" = "keenetic" ]; then
    MODE_LABEL="роутер"
  elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
    MODE_LABEL="OpenWRT"
  else
    MODE_LABEL="linux"
  fi

  msg "PhobosWG  ·  клиент: ${CLIENT_NAME}  ·  ${ROUTER_PLATFORM} (${ARCH})  ·  ${MODE_LABEL}  ·  ${PHOBOS_DIR}"

  if ! check_dependencies "$ROUTER_PLATFORM"; then
    exit 1
  fi

  if [ "$ROUTER_PLATFORM" = "keenetic" ] && [ "$PROTOCOL" = "socks5" ]; then
    _run_keenetic_socks5
  elif [ "$ROUTER_PLATFORM" = "keenetic" ]; then
    _run_keenetic
  elif [ "$ROUTER_PLATFORM" = "openwrt" ] && [ "$PROTOCOL" = "socks5" ]; then
    _run_openwrt_socks5
  elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
    _run_openwrt
  elif [ "$IS_3XUI_MODE" = "true" ] && [ "$PROTOCOL" = "socks5" ]; then
    _run_3xui_socks5
  elif [ "$IS_3XUI_MODE" = "true" ]; then
    _run_3xui
  else
    _run_linux
  fi
}

main "$@"
