#!/usr/bin/env bash

set -euo pipefail

#############################################
#           GLOBAL VARIABLES
#############################################

# Installation settings
DEFAULT_USERNAME="torrserver"
DEFAULT_INSTALL_DIR="/opt/torrserver"
DEFAULT_SERVICE_NAME="torrserver"
DEFAULT_PORT="8090"

# Runtime variables
username="${DEFAULT_USERNAME}"
dirInstall="${DEFAULT_INSTALL_DIR}"
serviceName="${DEFAULT_SERVICE_NAME}"
scriptname=$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")

# Flags
SILENT_MODE=0
USE_ROOT_USER=0
ROOT_PROMPTED=0

# Command-line state
parsedCommand=""
specificVersion=""
downgradeRelease=""
changeUserName=""

# Service configuration
servicePort=""
isAuth=""
isRdb=""
isLog=""
isBbr=""
isAuthUser=""
isAuthPass=""

# Constants
readonly REPO_URL="https://github.com/YouROK/TorrServer"
readonly REPO_API_URL="https://api.github.com/repos/YouROK/TorrServer"
readonly VERSION_PREFIX="MatriX"
readonly BINARY_NAME_PREFIX="TorrServer-linux"
readonly MIN_GLIBC_VERSION="2.32"
readonly MIN_VERSION_REQUIRING_GLIBC=136
readonly SYSCTL_BBR_FILE="/etc/sysctl.d/90-torrserver.conf"

# Color support
declare -A colors=([black]=0 [red]=1 [green]=2 [yellow]=3 [blue]=4 [magenta]=5 [cyan]=6 [white]=7)
supports_color_output=0

if command -v tput >/dev/null 2>&1 && [[ -t 1 ]]; then
  if [[ $(tput colors 2>/dev/null) -ge 8 ]]; then
    supports_color_output=1
  fi
fi

# Language
lang="en"

#############################################
#     TRANSLATION SYSTEM
#############################################

# Message dictionary
declare -A MSG_EN=(
  # General
  [lang_choice]="Choose Language:"
  [lang_english]="English"
  [lang_russian]="Русский"
  [your_lang]="Your language (Ваш язык): "
  [have_fun]="Have Fun!"

  # Script info
  [script_title]="TorrServer install and configuration script for Linux"

  # Checks
  [need_root]="Script must run as root or user with sudo privileges. Example: sudo $scriptname"
  [unsupported_arch]="Unsupported Arch. Can't continue."
  [unsupported_os]="It looks like you are running this installer on a system other than Debian, Ubuntu, Fedora, CentOS, Amazon Linux, Oracle Linux or Arch Linux."

  # User management
  [user_exists]="User %s exists!"
  [user_added]="User %s has been added to system!"
  [user_add_failed]="Failed to add %s user!"
  [user_removed]="User %s has been removed from system!"
  [user_remove_failed]="Failed to remove %s user!"
  [user_not_found]="%s - no such user!"

  # Version
  [downloading]="Downloading TorrServer"
  [target_version]="Target version:"
  [installed_version]="installed:"
  [target_label]="target:"
  [version_not_found]="ERROR: Version %s not found in releases"
  [check_versions]="Please check available versions at: $REPO_URL/releases"
  [already_installed]="You already have TorrServer %s installed"
  [have_latest]="You have latest TorrServer %s"
  [update_found]="TorrServer update found!"
  [will_install]="Will install TorrServer version %s"

  # Installation
  [installing_packages]="Installing missing packages…"
  [install_configure]="Install and configure TorrServer…"
  [starting_service]="Starting TorrServer…"
  [install_complete]="TorrServer %s installed to %s"
  [access_web]="You can now open your browser at http://%s:%s to access TorrServer web GUI."
  [use_auth]="Use user \"%s\" with password \"%s\" for authentication"

  # Prompts
  [want_update]="Want to update TorrServer?"
  [want_install]="Want to install or configure TorrServer? Type Delete to uninstall."
  [want_reconfigure]="Do you want to reconfigure TorrServer settings?"
  [change_port]="Change TorrServer web-port?"
  [enter_port]="Enter port number: "
  [enable_auth]="Enable server authorization?"
  [prompt_user]="User: "
  [prompt_password]="Password: "
  [change_auth_credentials]="Change authentication username and password?"
  [enable_rdb]="Start TorrServer in public read-only mode?"
  [enable_log]="Enable TorrServer log output to file?"
  [enable_bbr]="Enable BBR (recommended for better download speed)?"
  [confirm_delete]="Are you sure you want to delete TorrServer?"
  [prompt_run_as_root]="Run service as root user?"

  # Uninstall
  [install_dir_label]="TorrServer install dir -"
  [uninstall_warning]="This action will delete TorrServer including all it's torrents, settings and files on path above!"
  [uninstalled]="TorrServer uninstalled!"

  # Status
  [found_in]="TorrServer found in"
  [not_found]="TorrServer not found. It's not installed or have zero size."
  [no_version_info]="No version information available. Can be server issue."
  [config_updated]="Configuration updated successfully"
  [store_auth]="Store %s:%s to %s"
  [use_existing_auth]="Use existing auth from %s - %s"
  [set_readonly]="Set database to read-only mode…"
  [readonly_hint]="To change remove --rdb option from %s or rerun install script without parameters"
  [log_location]="TorrServer log stored at %s"
  [bbr_enabled]="BBR TCP congestion control enabled"
  [bbr_already_configured]="BBR is already configured"
  [bbr_configured_not_available]="BBR is configured but not available in this kernel"
  [bbr_config_failed]="Warning: Failed to configure BBR"
  [bbr_not_available]="BBR is not available in this kernel"
  [bbr_requires_kernel]="BBR requires Linux kernel 4.9+ with tcp_bbr module"
  [bbr_write_failed]="Failed to write to %s"
  [bbr_current_values]="Current: qdisc=%s, congestion_control=%s"
  [bbr_settings_will_apply]="BBR settings are in %s and will apply after reboot"
  [bbr_settings_not_added]="BBR settings were not added to %s"
  [bbr_activate_failed]="Warning: Could not activate BBR - module not available"
  [bbr_no_optimization]="Service will start without BBR optimization"
  [bbr_activate_failed_cc]="Warning: Could not activate BBR (currently: %s)"
  [systemctl_missing]="systemctl is not available. Skipping service management commands."
  [systemctl_failed]="Warning: systemctl %s failed"
  [service_start_failed]="Warning: TorrServer service failed to start. Check systemctl status for details."
  [user_change_success]="Service user changed to %s"
  [user_change_permissions]="Updated ownership of %s to %s:%s"
  [user_change_missing]="TorrServer installation not found in %s. Run install first."
  [user_change_invalid]="Only %s or %s are allowed for --change-user"

  # glibc
  [glibc_error]="ERROR: TorrServer version %s requires glibc >= $MIN_GLIBC_VERSION"
  [glibc_current]="Your system has glibc %s"
  [glibc_upgrade]="Please install a version < $MIN_VERSION_REQUIRING_GLIBC or upgrade your system"
  [glibc_detected]="Detected glibc version: %s"
  [glibc_ok]="OK: glibc version meets requirements for TorrServer %s"
  [glibc_no_requirement]="TorrServer version %s: no special glibc requirements"
  [glibc_warning]="Warning: Could not detect glibc version"
  [glibc_may_fail]="TorrServer version %s requires glibc >= $MIN_GLIBC_VERSION"
  [glibc_install_may_fail]="Installation may fail if your system doesn't meet this requirement"
  [update_cancelled]="Update cancelled due to glibc incompatibility"
  [downgrade_cancelled]="Downgrade cancelled due to glibc incompatibility"

  # OS version errors
  [os_not_supported]="Your %s version is not supported."
  [os_script_supports]="Script supports only %s %s"

  # User mode
  [running_as_root]="Service will run as root user"
  [running_as_user]="Service will run as %s user"

  # Error messages
  [error_username_required]="Error: Username required for --change-user"
  [error_version_required]="Error: Version number required for downgrade"
  [error_version_example]="Example: %s -d 101"
  [error_unknown_option]="Unknown option: %s"
  [installing_specific_version]="Installing specific version: %s"
  [service_reconfigured_user]="Service reconfigured for user: %s"
  [install_first_required]="Please install TorrServer first using: %s --install"
)

declare -A MSG_RU=(
  # General
  [lang_choice]="Choose Language:"
  [lang_english]="English"
  [lang_russian]="Русский"
  [your_lang]="Your language (Ваш язык): "
  [have_fun]="Have Fun!"

  # Script info
  [script_title]="Скрипт установки, удаления и настройки TorrServer для Linux"

  # Checks
  [need_root]="Вам нужно запустить скрипт от root или пользователя с правами sudo. Пример: sudo $scriptname"
  [unsupported_arch]="Не поддерживаемая архитектура. Продолжение невозможно."
  [unsupported_os]="Похоже, что вы запускаете этот установщик в системе отличной от Debian, Ubuntu, Fedora, CentOS, Amazon Linux, Oracle Linux или Arch Linux."

  # User management
  [user_exists]="пользователь %s найден!"
  [user_added]="пользователь %s добавлен!"
  [user_add_failed]="не удалось добавить пользователя %s!"
  [user_removed]="Пользователь %s удален!"
  [user_remove_failed]="не удалось удалить пользователя %s!"
  [user_not_found]="пользователь %s не найден!"

  # Version
  [downloading]="Загружаем TorrServer"
  [target_version]="Устанавливаемая версия:"
  [installed_version]="установлен:"
  [target_label]="устанавливаемая:"
  [version_not_found]="ОШИБКА: Версия %s не найдена в релизах"
  [check_versions]="Проверьте доступные версии по адресу: $REPO_URL/releases"
  [already_installed]="TorrServer %s уже установлен"
  [have_latest]="Установлен TorrServer последней версии %s"
  [update_found]="Доступно обновление сервера"
  [will_install]="Будет установлена версия TorrServer %s"

  # Installation
  [installing_packages]="Устанавливаем недостающие пакеты…"
  [install_configure]="Устанавливаем и настраиваем TorrServer…"
  [starting_service]="Запускаем службу TorrServer…"
  [install_complete]="TorrServer %s установлен в директории %s"
  [access_web]="Теперь вы можете открыть браузер по адресу http://%s:%s для доступа к вебу TorrServer"
  [use_auth]="Для авторизации используйте пользователя «%s» с паролем «%s»"

  # Prompts
  [want_update]="Хотите обновить TorrServer?"
  [want_install]="Хотите установить, обновить или настроить TorrServer? Для удаления введите «Delete»"
  [want_reconfigure]="Хотите перенастроить параметры TorrServer?"
  [change_port]="Хотите изменить порт для TorrServer?"
  [enter_port]="Введите номер порта: "
  [enable_auth]="Включить авторизацию на сервере?"
  [prompt_user]="Пользователь: "
  [prompt_password]="Пароль: "
  [change_auth_credentials]="Изменить имя пользователя и пароль для авторизации?"
  [enable_rdb]="Запускать TorrServer в публичном режиме без возможности изменения настроек через веб сервера?"
  [enable_log]="Включить запись журнала работы TorrServer в файл?"
  [enable_bbr]="Включить BBR (рекомендуется для лучшей скорости загрузки)?"
  [confirm_delete]="Вы уверены что хотите удалить программу?"
  [prompt_run_as_root]="Запускать службу от пользователя root?"

  # Uninstall
  [install_dir_label]="Директория c TorrServer -"
  [uninstall_warning]="Это действие удалит все данные TorrServer включая базу данных торрентов и настройки по указанному выше пути!"
  [uninstalled]="TorrServer удален из системы!"

  # Status
  [found_in]="TorrServer найден в директории"
  [not_found]="TorrServer не найден, возможно он не установлен или размер бинарника равен 0."
  [no_version_info]="Информация о версии недоступна. Возможно сервер не доступен."
  [config_updated]="Конфигурация успешно обновлена"
  [store_auth]="Сохраняем %s:%s в %s"
  [use_existing_auth]="Используйте реквизиты из %s для авторизации - %s"
  [set_readonly]="База данных устанавливается в режим «только для чтения»…"
  [readonly_hint]="Для изменения отредактируйте %s, убрав опцию --rdb или запустите интерактивную установку без параметров повторно"
  [log_location]="лог TorrServer располагается по пути %s"
  [bbr_enabled]="Включено управление перегрузкой TCP BBR"
  [bbr_already_configured]="BBR уже настроен"
  [bbr_configured_not_available]="BBR настроен, но недоступен в этом ядре"
  [bbr_config_failed]="Предупреждение: Не удалось настроить BBR"
  [bbr_not_available]="BBR недоступен в этом ядре"
  [bbr_requires_kernel]="BBR требует Linux kernel 4.9+ с модулем tcp_bbr"
  [bbr_write_failed]="Не удалось записать в %s"
  [bbr_current_values]="Текущие значения: qdisc=%s, congestion_control=%s"
  [bbr_settings_will_apply]="Настройки BBR находятся в %s и вступят в силу после перезагрузки"
  [bbr_settings_not_added]="Настройки BBR не были добавлены в %s"
  [bbr_activate_failed]="Предупреждение: Не удалось активировать BBR - модуль недоступен"
  [bbr_no_optimization]="Служба запустится без оптимизации BBR"
  [bbr_activate_failed_cc]="Предупреждение: Не удалось активировать BBR (текущее: %s)"
  [systemctl_missing]="systemctl недоступен. Пропускаем команды управления службой."
  [systemctl_failed]="Предупреждение: команда systemctl %s завершилась ошибкой"
  [service_start_failed]="Предупреждение: служба TorrServer не запустилась. Проверьте systemctl status для деталей."
  [user_change_success]="Сервис TorrServer теперь запускается от пользователя %s"
  [user_change_permissions]="Обновлены права на %s: %s:%s"
  [user_change_missing]="Установка TorrServer не найдена в %s. Сначала выполните установку."
  [user_change_invalid]="Параметр --change-user принимает только %s или %s"

  # glibc
  [glibc_error]="ОШИБКА: TorrServer версии %s требует glibc >= $MIN_GLIBC_VERSION"
  [glibc_current]="В вашей системе установлена glibc %s"
  [glibc_upgrade]="Пожалуйста, установите версию < $MIN_VERSION_REQUIRING_GLIBC или обновите систему"
  [glibc_detected]="Обнаружена версия glibc: %s"
  [glibc_ok]="OK: версия glibc соответствует требованиям для TorrServer %s"
  [glibc_no_requirement]="TorrServer версии %s: нет особых требований к glibc"
  [glibc_warning]="Предупреждение: Не удалось определить версию glibc"
  [glibc_may_fail]="TorrServer версии %s требует glibc >= $MIN_GLIBC_VERSION"
  [glibc_install_may_fail]="Установка может завершиться неудачей, если система не соответствует требованиям"
  [update_cancelled]="Обновление отменено из-за несовместимости glibc"
  [downgrade_cancelled]="Понижение версии отменено из-за несовместимости glibc"

  # OS version errors
  [os_not_supported]="Ваша версия %s не поддерживается."
  [os_script_supports]="Скрипт поддерживает только %s %s"

  # User mode
  [running_as_root]="Служба будет запущена от пользователя root"
  [running_as_user]="Служба будет запущена от пользователя %s"

  # Error messages
  [error_username_required]="Ошибка: Требуется имя пользователя для --change-user"
  [error_version_required]="Ошибка: Требуется номер версии для понижения версии"
  [error_version_example]="Пример: %s -d 101"
  [error_unknown_option]="Неизвестная опция: %s"
  [installing_specific_version]="Установка конкретной версии: %s"
  [service_reconfigured_user]="Служба перенастроена для пользователя: %s"
  [install_first_required]="Пожалуйста, сначала установите TorrServer используя: %s --install"
)

# Translation function
msg() {
  local key="$1"
  shift
  local message=""

  if [[ $lang == "ru" ]]; then
    message="${MSG_RU[$key]:-$key}"
  else
    message="${MSG_EN[$key]:-$key}"
  fi

  # Apply printf formatting if additional arguments provided
  if [[ $# -gt 0 ]]; then
    # shellcheck disable=SC2059
    printf "$message" "$@"
  else
    printf '%s\n' "$message"
  fi
}

#############################################
#     UTILITY FUNCTIONS
#############################################

colorize() {
  if [[ $supports_color_output -eq 1 ]]; then
    printf "%s%s%s" "$(tput setaf "${colors[$1]:-7}")" "$2" "$(tput op)"
  else
    printf "%s" "$2"
  fi
}

# Highlight first letter of a word with specified color
highlightFirstLetter() {
  local color="$1"
  local word="$2"
  local first_char="${word:0:1}"
  local rest="${word:1}"
  printf "%s%s" "$(colorize "$color" "$first_char")" "$rest"
}

isRoot() {
  [[ $EUID -eq 0 ]]
}

getBinaryName() {
  echo "${BINARY_NAME_PREFIX}-${architecture}"
}

getVersionTag() {
  local version="$1"
  echo "${VERSION_PREFIX}.${version}"
}

buildDownloadUrl() {
  local target_version="$1"
  local binary_name="$2"

  if [[ "$target_version" == "latest" ]]; then
    echo "${REPO_URL}/releases/latest/download/${binary_name}"
  else
    echo "${REPO_URL}/releases/download/${target_version}/${binary_name}"
  fi
}

getLang() {
  lang=$(locale | grep LANG | cut -d= -f2 | tr -d '"' | cut -d_ -f1)
  if [[ $lang != "ru" ]]; then
    lang="en"
  fi
}

getIP() {
  local ip="localhost"

  if command -v dig >/dev/null 2>&1; then
    ip=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null || echo "")
    if [[ -z "$ip" ]]; then
      ip="localhost"
    fi
  elif command -v host >/dev/null 2>&1; then
    local host_output=""
    host_output=$(host myip.opendns.com resolver1.opendns.com 2>/dev/null || true)
    ip=$(printf "%s\n" "$host_output" | tail -n1 | awk '{print $NF}')
    if [[ -z "$ip" ]]; then
      ip="localhost"
    fi
  fi

  serverIP="$ip"
}

promptYesNo() {
  local prompt="$1"
  local default="${2:-n}"
  local recommended="${3:-$default}"

  if [[ $SILENT_MODE -eq 1 ]]; then
    if [[ "$default" == "y" ]]; then
      return 0
    else
      return 1
    fi
  fi

  # Determine colors based on recommendation
  local yes_color no_color
  if [[ "$recommended" == "y" ]]; then
    yes_color="green"
    no_color="red"
  else
    yes_color="red"
    no_color="green"
  fi

  # Define localized Yes/No words
  local yes_word no_word
  if [[ $lang == "ru" ]]; then
    yes_word="Да"
    no_word="Нет"
  else
    yes_word="Yes"
    no_word="No"
  fi

  # Highlight first letter of each word
  local yes_text
  local no_text
  yes_text="$(highlightFirstLetter "$yes_color" "$yes_word")"
  no_text="$(highlightFirstLetter "$no_color" "$no_word")"

  local answer
  IFS= read -r -p " $prompt ($yes_text/$no_text) " answer </dev/tty

  # Support both English (Yy) and Russian (Дд) for Yes
  if [[ "$answer" =~ ^[YyДд] ]]; then
    return 0
  else
    return 1
  fi
}

promptYesNoDelete() {
  local prompt="$1"
  local default="${2:-n}"
  local recommended="${3:-$default}"

  if [[ $SILENT_MODE -eq 1 ]]; then
    if [[ "$default" == "y" ]]; then
      echo "yes"
    else
      echo "no"
    fi
    return
  fi

  # Determine colors based on recommended answer
  local yes_color no_color
  if [[ "$recommended" == "y" ]]; then
    yes_color="green"
    no_color="red"
  else
    yes_color="red"
    no_color="green"
  fi

  # Define localized Yes/No words
  local yes_word no_word
  if [[ $lang == "ru" ]]; then
    yes_word="Да"
    no_word="Нет"
  else
    yes_word="Yes"
    no_word="No"
  fi

  # Highlight first letter of each word
  local yes_text
  local no_text
  yes_text="$(highlightFirstLetter "$yes_color" "$yes_word")"
  no_text="$(highlightFirstLetter "$no_color" "$no_word")"

  local answer
  IFS= read -r -p " $prompt ($yes_text/$no_text) " answer </dev/tty
  answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]' | xargs)

  # Check for Delete (case-insensitive, supports both English and Russian)
  if [[ "$answer" == "delete" ]] || [[ "$answer" == "удалить" ]] || [[ "$answer" == "удаление" ]]; then
    echo "delete"
  elif [[ "$answer" =~ ^[YyДд] ]]; then
    echo "yes"
  else
    echo "no"
  fi
}

promptInput() {
  local prompt="$1"
  local default="$2"

  if [[ $SILENT_MODE -eq 1 ]]; then
    echo "$default"
    return
  fi

  local answer
  IFS= read -r -p " $prompt " answer </dev/tty
  echo "${answer:-$default}"
}

systemctlCmd() {
  local quiet=0
  if [[ ${1:-} == "--quiet" ]]; then
    quiet=1
    shift
  fi

  if ! command -v systemctl >/dev/null 2>&1; then
    if [[ $quiet -eq 0 && $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg systemctl_missing)"
    fi
    return 1
  fi

  local rc
  systemctl "$@" >/dev/null 2>&1
  rc=$?
  if [[ $rc -ne 0 ]]; then
    if [[ $quiet -eq 0 && $SILENT_MODE -eq 0 ]]; then
      printf " - %s\n" "$(msg systemctl_failed "$*")"
    fi
    return $rc
  fi

  return 0
}

#############################################
#     VERSION MANAGEMENT
#############################################

getLatestRelease() {
  curl -s "${REPO_API_URL}/releases/latest" |
  grep -iE '"tag_name":|"version":' |
  sed -E 's/.*"([^"]+)".*/\1/' |
  head -n1
}

getSpecificRelease() {
  local version="$1"
  local tag_name
  tag_name=$(getVersionTag "$version")
  local response
  response=$(curl -s "${REPO_API_URL}/releases/tags/$tag_name")

  if echo "$response" | grep -q '"tag_name"'; then
    echo "$tag_name"
  else
    echo ""
  fi
}

getTargetVersion() {
  if [[ -n "$specificVersion" ]]; then
  local target_release
  target_release=$(getSpecificRelease "$specificVersion")
    if [[ -z "$target_release" ]]; then
      echo " - $(colorize red "$(msg version_not_found "$specificVersion")")"
      echo " - $(msg check_versions)"
      exit 1
    fi
    echo "$target_release"
  else
    getLatestRelease
  fi
}

downloadBinary() {
  local url="$1"
  local destination="$2"
  local version_info="$3"

  local curl_args=(-L)

  if [[ $SILENT_MODE -eq 0 ]]; then
    echo " - $(msg downloading) $version_info..."
    curl_args+=(--progress-bar -#)
  else
    curl_args+=(-s -S)
  fi

  curl "${curl_args[@]}" -o "$destination" "$url"
  chmod +x "$destination"
}

#############################################
#     GLIBC COMPATIBILITY
#############################################

getGlibcVersion() {
  local glibc_version

  # Try ldd --version (most reliable)
  if command -v ldd >/dev/null 2>&1; then
    glibc_version=$(ldd --version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1)
    if [[ -n "$glibc_version" ]]; then
      echo "$glibc_version"
      return 0
    fi
  fi

  # Try getconf GNU_LIBC_VERSION
  if command -v getconf >/dev/null 2>&1; then
    glibc_version=$(getconf GNU_LIBC_VERSION 2>/dev/null | grep -oE '[0-9]+\.[0-9]+')
    if [[ -n "$glibc_version" ]]; then
      echo "$glibc_version"
      return 0
    fi
  fi

  # Try rpm package manager
  if command -v rpm >/dev/null 2>&1; then
    glibc_version=$(rpm -q glibc 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -n1)
    if [[ -n "$glibc_version" ]]; then
      echo "$glibc_version"
      return 0
    fi
  fi

  # Try dpkg package manager
  if command -v dpkg >/dev/null 2>&1; then
    glibc_version=$(dpkg -l libc6 2>/dev/null | awk '/^ii/ {print $3}' | grep -oE '[0-9]+\.[0-9]+' | head -n1)
    if [[ -n "$glibc_version" ]]; then
      echo "$glibc_version"
      return 0
    fi
  fi

  return 1
}

compareVersions() {
  local ver1="$1"
  local ver2="$2"
  local sorted_first
  sorted_first=$(printf '%s\n' "$ver1" "$ver2" | sort -V | head -n1)
  [[ "$sorted_first" == "$ver2" ]]
}

checkGlibcCompatibility() {
  local target_version="$1"
  local version_number

  # Extract numeric version
  if [[ "$target_version" =~ ${VERSION_PREFIX}\.([0-9]+) ]]; then
    version_number="${BASH_REMATCH[1]}"
  elif [[ "$target_version" =~ ^[0-9]+$ ]]; then
    version_number="$target_version"
  else
    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg glibc_warning)"
    fi
    return 0
  fi

  # Check if version requires glibc 2.32+
  if [[ $version_number -ge $MIN_VERSION_REQUIRING_GLIBC ]]; then
  local current_glibc
  current_glibc=$(getGlibcVersion)

    if [[ -z "$current_glibc" ]]; then
      if [[ $SILENT_MODE -eq 0 ]]; then
        echo " - $(msg glibc_warning)"
        echo " - $(msg glibc_may_fail "$target_version")"
        echo " - $(msg glibc_install_may_fail)"
      fi
      return 0
    fi

    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg glibc_detected "$current_glibc")"
    fi

    if ! compareVersions "$current_glibc" "$MIN_GLIBC_VERSION"; then
      echo " - $(colorize red "$(msg glibc_error "$target_version")")"
      echo " - $(msg glibc_current "$current_glibc")"
      echo " - $(msg glibc_upgrade)"
      return 1
    fi

    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(colorize green "$(msg glibc_ok "$target_version")")"
    fi
  else
    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg glibc_no_requirement "$target_version")"
    fi
  fi

  return 0
}

#############################################
#     USER MANAGEMENT
#############################################

addUser() {
  if ! isRoot; then
    return 1
  fi

  if [[ $username == "root" ]]; then
    return 0
  fi

  if id "$username" >/dev/null 2>&1; then
    if [[ $SILENT_MODE -eq 0 ]]; then
      printf " - %s\n" "$(msg user_exists "$username")"
    fi
    return 0
  else
    if useradd --home-dir "$dirInstall" --create-home --shell /bin/false -c "TorrServer" "$username" 2>/dev/null; then
      chmod 755 "$dirInstall"
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf " - %s\n" "$(msg user_added "$username")"
      fi
      return 0
    else
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf " - %s\n" "$(msg user_add_failed "$username")"
      fi
      return 1
    fi
  fi
}

delUser() {
  if ! isRoot; then
    return 1
  fi

  if [[ $username == "root" ]]; then
    return 0
  fi

  if id "$username" >/dev/null 2>&1; then
    if userdel --remove "$username" 2>/dev/null; then
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf " - %s\n" "$(msg user_removed "$username")"
      fi
      return 0
    else
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf " - %s\n" "$(msg user_remove_failed "$username")"
      fi
      return 1
    fi
  else
    if [[ $SILENT_MODE -eq 0 ]]; then
      printf " - %s\n" "$(msg user_not_found "$username")"
    fi
    return 1
  fi
}

#############################################
#     OS DETECTION & PACKAGES
#############################################

installPackages() {
  local pkg_type="$1"
  shift
  local packages=("$@")

  case "$pkg_type" in
    deb)
      local missing=()
      for pkg in "${packages[@]}"; do
        if ! dpkg -s "$pkg" >/dev/null 2>&1; then
          missing+=("$pkg")
        fi
      done
      if [[ ${#missing[@]} -gt 0 ]]; then
        if [[ $SILENT_MODE -eq 0 ]]; then
          echo " $(msg installing_packages)"
        fi
        apt update >/dev/null 2>&1
        apt -y install "${missing[@]}"
      fi
      ;;
    rpm)
      local pkg_manager="$1"
      shift
      packages=("$@")
      local needs_update=0
      for pkg in "${packages[@]}"; do
        if [[ -z "$(rpm -qa "$pkg" 2>/dev/null)" ]]; then
          needs_update=1
          break
        fi
      done
      if [[ $needs_update -eq 1 ]]; then
        if [[ "$pkg_manager" == "dnf" ]]; then
          dnf makecache -q >/dev/null 2>&1 || true
        elif [[ "$pkg_manager" == "yum" ]]; then
          yum makecache fast -q >/dev/null 2>&1 || true
        fi
        for pkg in "${packages[@]}"; do
          if [[ -z "$(rpm -qa "$pkg" 2>/dev/null)" ]]; then
            $pkg_manager -y install "$pkg"
          fi
        done
      fi
      ;;
    arch)
      local missing=()
      for pkg in "${packages[@]}"; do
        if ! pacman -Q "$pkg" >/dev/null 2>&1; then
          missing+=("$pkg")
        fi
      done
      if [[ ${#missing[@]} -gt 0 ]]; then
        pacman -Sy --noconfirm >/dev/null 2>&1
        pacman -S --noconfirm "${missing[@]}"
      fi
      ;;
  esac
}

getRpmPackageManager() {
  local version_id="$1"

  if [[ "$version_id" =~ ^[0-9]+$ ]] && [[ $version_id -ge 8 ]] && command -v dnf >/dev/null 2>&1; then
    echo "dnf"
  elif command -v dnf >/dev/null 2>&1; then
    echo "dnf"
  else
    echo "yum"
  fi
}

validateOSVersion() {
  local os_name="$1"
  local supported_versions="$2"
  local version_id="$3"

  local major_version
  major_version=$(echo "$version_id" | cut -d '.' -f1)

  if [[ ! $major_version =~ ^($supported_versions)$ ]]; then
    echo ""
    echo " $(msg os_not_supported "$os_name")"
    echo ""
    echo " $(msg os_script_supports "$os_name" "$supported_versions")"
    echo ""
    exit 1
  fi
}

checkOS() {
  if [[ -e /etc/debian_version ]]; then
    # shellcheck source=/dev/null
    source /etc/os-release

    if [[ $ID == "debian" || $ID == "raspbian" ]]; then
      local current_version_id
      current_version_id="${VERSION_ID:-}"
      if [[ -n "$current_version_id" && $current_version_id -lt 6 ]]; then
        validateOSVersion "Debian" ">=6" "$current_version_id"
      fi
    elif [[ $ID == "ubuntu" ]]; then
      local current_version_id
      current_version_id="${VERSION_ID:-}"
      local major
      major=$(echo "$current_version_id" | cut -d '.' -f1)
      if [[ -n "$current_version_id" && $major -lt 10 ]]; then
        validateOSVersion "Ubuntu" ">=10" "$current_version_id"
      fi
    fi

    installPackages deb curl iputils-ping dnsutils

  elif [[ -e /etc/system-release ]]; then
    # shellcheck source=/dev/null
    source /etc/os-release
    local pkg_manager

    case "$ID" in
      fedora)
        pkg_manager=$(getRpmPackageManager "${VERSION_ID%%.*}")
        installPackages rpm "$pkg_manager" curl iputils bind-utils
        ;;
      centos|redhat)
        validateOSVersion "CentOS/RedHat" "7|8|9|10" "$VERSION_ID"
        pkg_manager=$(getRpmPackageManager "${VERSION_ID%%.*}")
        installPackages rpm "$pkg_manager" curl iputils bind-utils
        ;;
      rocky)
        validateOSVersion "RockyLinux" "8|9|10" "$VERSION_ID"
        pkg_manager=$(getRpmPackageManager "${VERSION_ID%%.*}")
        installPackages rpm "$pkg_manager" curl iputils bind-utils
        ;;
      almalinux)
        validateOSVersion "AlmaLinux" "8|9|10" "$VERSION_ID"
        pkg_manager=$(getRpmPackageManager "${VERSION_ID%%.*}")
        installPackages rpm "$pkg_manager" curl iputils bind-utils
        ;;
      ol)
        validateOSVersion "Oracle Linux" "8|9|10" "$VERSION_ID"
        pkg_manager=$(getRpmPackageManager "${VERSION_ID%%.*}")
        installPackages rpm "$pkg_manager" curl iputils bind-utils
        ;;
      amzn)
        if [[ $VERSION_ID != "2" ]]; then
          validateOSVersion "Amazon Linux" "2" "$VERSION_ID"
        fi
        installPackages rpm yum curl iputils bind-utils
        ;;
    esac

  elif [[ -e /etc/arch-release ]]; then
    installPackages arch curl iputils bind-tools

  else
    echo " $(msg unsupported_os)"
    exit 1
  fi
}

checkArch() {
  case $(uname -m) in
    i386|i686) architecture="386" ;;
    x86_64) architecture="amd64" ;;
    aarch64) architecture="arm64" ;;
    armv7|armv7l) architecture="arm7" ;;
    armv6|armv6l) architecture="arm5" ;;
    *)
      echo " $(msg unsupported_arch)"
      exit 1
      ;;
  esac
}

initialCheck() {
  if ! isRoot; then
    echo " $(msg need_root)"
    exit 1
  fi

  checkOS
  checkArch
}

#############################################
#     INSTALLATION FUNCTIONS
#############################################

checkInstalled() {
  # Set username based on USE_ROOT_USER flag
  if [[ $USE_ROOT_USER -eq 1 ]]; then
    username="root"
  else
    username="${DEFAULT_USERNAME}"
    if ! addUser; then
      username="root"
    fi
  fi

  local binName
  binName=$(getBinaryName)
  if [[ -f "$dirInstall/$binName" ]] && [[ $(stat -c%s "$dirInstall/$binName" 2>/dev/null) -ne 0 ]]; then
    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg found_in) $dirInstall"
    fi
    return 0
  else
    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg not_found)"
    fi
    return 1
  fi
}

checkInstalledVersion() {
  local binName
  binName=$(getBinaryName)
  local target_version
  target_version=$(getTargetVersion)
  local installed_version
  installed_version="$("$dirInstall/$binName" --version 2>/dev/null | awk '{print $2}')"

  if [[ -z "$target_version" ]]; then
    echo " - $(msg no_version_info)"
    exit 1
  fi

  if [[ "$target_version" == "$installed_version" ]]; then
    if [[ -n "$specificVersion" ]]; then
      if [[ $SILENT_MODE -eq 0 ]]; then
        echo " - $(msg already_installed "$target_version")"
      fi
    else
      if [[ $SILENT_MODE -eq 0 ]]; then
        echo " - $(msg have_latest "$target_version")"
      fi
    fi
    return 0
  else
    if [[ $SILENT_MODE -eq 0 ]]; then
      if [[ -n "$specificVersion" ]]; then
        echo " - $(msg will_install "$target_version")"
      else
        echo " - $(msg update_found)"
      fi
      echo "   $(msg installed_version) \"$installed_version\""
      echo "   $(msg target_label) \"$target_version\""
    fi
    return 1
  fi
}

createServiceFile() {
  cat << EOF > "$dirInstall/$serviceName.service"
[Unit]
Description=TorrServer - stream torrent to http
Wants=network-online.target
After=network.target

[Service]
User=$username
Group=$username
Type=simple
NonBlocking=true
EnvironmentFile=$dirInstall/$serviceName.config
ExecStart=${dirInstall}/$(getBinaryName) \$DAEMON_OPTIONS
ExecReload=/bin/kill -HUP \$MAINPID
ExecStop=/bin/kill -INT \$MAINPID
TimeoutSec=30
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF
}

# Check if BBR is available in the kernel
isBBRAvailable() {
  sysctl net.ipv4.tcp_available_congestion_control 2>/dev/null | grep -qw "bbr"
}

# Load BBR kernel module
loadBBRModule() {
  local max_attempts=3
  local attempt=0

  while [[ $attempt -lt $max_attempts ]]; do
    if modprobe tcp_bbr >/dev/null 2>&1; then
      sleep 0.3
      if isBBRAvailable; then
        return 0
      fi
    fi
    ((attempt++))
    sleep 0.2
  done

  return 1
}

# Ensure BBR module loads at boot
ensureBBRModuleAtBoot() {
  local modules_dir="/etc/modules-load.d"
  local modules_file="$modules_dir/bbr.conf"

  [[ -d "$modules_dir" ]] || mkdir -p "$modules_dir" 2>/dev/null || return 1
  if [[ ! -f "$modules_file" ]] || ! grep -q "^tcp_bbr$" "$modules_file" 2>/dev/null; then
    echo "tcp_bbr" >> "$modules_file" 2>/dev/null || return 1
  fi
  return 0
}

# Check if BBR is configured in sysctl.d file
isBBRConfiguredInFile() {
  [[ -f "$SYSCTL_BBR_FILE" ]] && \
    grep -q "^net.core.default_qdisc=fq" "$SYSCTL_BBR_FILE" 2>/dev/null && \
    grep -q "^net.ipv4.tcp_congestion_control=bbr" "$SYSCTL_BBR_FILE" 2>/dev/null
}

# Add BBR settings to sysctl.d file
addBBRToSysctl() {
  if ! grep -q "^net.core.default_qdisc=fq" "$SYSCTL_BBR_FILE" 2>/dev/null; then
    echo "net.core.default_qdisc=fq" >> "$SYSCTL_BBR_FILE" 2>/dev/null || return 1
  fi
  if ! grep -q "^net.ipv4.tcp_congestion_control=bbr" "$SYSCTL_BBR_FILE" 2>/dev/null; then
    echo "net.ipv4.tcp_congestion_control=bbr" >> "$SYSCTL_BBR_FILE" 2>/dev/null || return 1
  fi
  return 0
}

# Check if BBR is currently active in the kernel
isBBRActive() {
  local current_cc
  current_cc=$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null || echo "")
  [[ "$current_cc" == "bbr" ]]
}

# Apply BBR settings to kernel (non-critical - returns status for logging only)
applyBBRSettings() {
  sysctl -w net.core.default_qdisc=fq >/dev/null 2>&1 || true
  if sysctl -w net.ipv4.tcp_congestion_control=bbr >/dev/null 2>&1; then
    sleep 0.2
    isBBRActive && return 0
  fi
  return 1
}

# Ensure BBR is active (non-critical - always returns success)
ensureBBRActive() {
  ! isBBRConfiguredInFile && return 0
  isBBRActive && return 0

  if ! isBBRAvailable && ! loadBBRModule; then
    [[ $SILENT_MODE -eq 0 ]] && {
      echo " - $(colorize yellow "$(msg bbr_activate_failed)")"
      echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
    }
    return 0
  fi

  if applyBBRSettings; then
    [[ $SILENT_MODE -eq 0 ]] && echo " - $(msg bbr_enabled)"
  else
    local current_cc
    current_cc=$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null || echo "unknown")
    [[ $SILENT_MODE -eq 0 ]] && {
      echo " - $(colorize yellow "$(msg bbr_activate_failed_cc "$current_cc")")"
      echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
      echo "   $(colorize yellow "$(msg bbr_settings_will_apply "$SYSCTL_BBR_FILE")")"
    }
  fi
  return 0
}

configureBBR() {
  [[ $isBbr -ne 1 ]] && return 0

  # Check if BBR is available or can be loaded first
  if ! isBBRAvailable && ! loadBBRModule; then
    # BBR not available - check if it's already in config
    if isBBRConfiguredInFile; then
      [[ $SILENT_MODE -eq 0 ]] && {
        echo " - $(colorize yellow "$(msg bbr_configured_not_available)")"
        echo "   $(colorize yellow "$(msg bbr_requires_kernel)")"
        echo "   $(colorize yellow "$(msg bbr_settings_will_apply "$SYSCTL_BBR_FILE")")"
        echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
      }
    else
      # Not in config and not available - don't add it
      [[ $SILENT_MODE -eq 0 ]] && {
        echo " - $(colorize yellow "$(msg bbr_not_available)")"
        echo "   $(colorize yellow "$(msg bbr_requires_kernel)")"
        echo "   $(colorize yellow "$(msg bbr_settings_not_added "$SYSCTL_BBR_FILE")")"
        echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
      }
    fi
    return 0
  fi

  # BBR is available - now configure it
  if isBBRConfiguredInFile; then
    [[ $SILENT_MODE -eq 0 ]] && echo " - $(msg bbr_already_configured)"
  else
    ! addBBRToSysctl && {
      [[ $SILENT_MODE -eq 0 ]] && {
        echo " - $(colorize yellow "$(msg bbr_config_failed)")"
        echo "   $(colorize yellow "$(msg bbr_write_failed "$SYSCTL_BBR_FILE")")"
        echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
      }
      return 0
    }
  fi

  ensureBBRModuleAtBoot || true

  if applyBBRSettings; then
    [[ $SILENT_MODE -eq 0 ]] && echo " - $(msg bbr_enabled)"
    return 0
  fi

  local current_cc current_qdisc
  current_cc=$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null || echo "unknown")
  current_qdisc=$(sysctl -n net.core.default_qdisc 2>/dev/null || echo "unknown")
  [[ $SILENT_MODE -eq 0 ]] && {
    echo " - $(colorize yellow "$(msg bbr_config_failed)")"
    echo "   $(colorize yellow "$(msg bbr_current_values "$current_qdisc" "$current_cc")")"
    echo "   $(colorize yellow "$(msg bbr_settings_will_apply "$SYSCTL_BBR_FILE")")"
    echo "   $(colorize yellow "$(msg bbr_no_optimization)")"
  }
  return 0
}

readExistingConfig() {
  local config_file="$dirInstall/$serviceName.config"

  if [[ -f "$config_file" ]]; then
    local daemon_options
    daemon_options=$(grep "^DAEMON_OPTIONS=" "$config_file" | cut -d'"' -f2)

    # Extract port - use -- to prevent grep from interpreting pattern as option
    if echo "$daemon_options" | grep -qE -- "--port[[:space:]]+[0-9]+"; then
      servicePort=$(echo "$daemon_options" | grep -oE -- "--port[[:space:]]+[0-9]+" | awk '{print $2}')
    fi

    # Check for auth
    if echo "$daemon_options" | grep -qE -- "--httpauth"; then
      isAuth=1
    else
      isAuth=0
    fi

    # Check for rdb
    if echo "$daemon_options" | grep -qE -- "--rdb"; then
      isRdb=1
    else
      isRdb=0
    fi

    # Check for log
    if echo "$daemon_options" | grep -qE -- "--logpath"; then
      isLog=1
    else
      isLog=0
    fi
  fi
}

configureService() {
  # Read existing config if available (for reconfiguration)
  if [[ -f "$dirInstall/$serviceName.config" ]]; then
    readExistingConfig
  fi

  # Port configuration
  if [[ -z "$servicePort" ]]; then
    local inferred_default="$DEFAULT_PORT"
    if promptYesNo "$(msg change_port)" "n" "y"; then
      servicePort=$(promptInput "$(msg enter_port)" "$inferred_default")
    else
      servicePort="$inferred_default"
    fi
  else
    # Port exists, ask if user wants to change it
    if [[ $SILENT_MODE -eq 0 ]]; then
      if promptYesNo "$(msg change_port)" "n" "y"; then
        servicePort=$(promptInput "$(msg enter_port)" "$servicePort")
      fi
    fi
  fi

  # Auth configuration
  if [[ -z "$isAuth" ]]; then
    if promptYesNo "$(msg enable_auth)" "n" "y"; then
      isAuth=1
    else
      isAuth=0
    fi
  else
    # Auth setting exists, ask if user wants to change it
    if [[ $SILENT_MODE -eq 0 ]]; then
      local current_auth_default
      current_auth_default="$([[ $isAuth -eq 1 ]] && echo 'y' || echo 'n')"
      if promptYesNo "$(msg enable_auth)" "$current_auth_default" "y"; then
        isAuth=1
      else
        isAuth=0
      fi
    fi
  fi

  # Setup auth if enabled
  if [[ $isAuth -eq 1 ]]; then
    if [[ ! -f "$dirInstall/accs.db" ]]; then
      isAuthUser=$(promptInput "$(msg prompt_user)" "admin")
      isAuthPass=$(promptInput "$(msg prompt_password)" "admin")
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf ' %s\n' "$(msg store_auth "$isAuthUser" "$isAuthPass" "${dirInstall}/accs.db")"
      fi
      echo -e "{\n  \"$isAuthUser\": \"$isAuthPass\"\n}" > "$dirInstall/accs.db"
    else
      local auth
      auth=$(cat "$dirInstall/accs.db" | head -2 | tail -1 | tr -d '[:space:]' | tr -d '"')
      if [[ $SILENT_MODE -eq 0 ]]; then
        printf ' - %s\n' "$(msg use_existing_auth "${dirInstall}/accs.db" "$auth")"
        # Ask if user wants to change credentials
        if promptYesNo "$(msg change_auth_credentials)" "n" "n"; then
          isAuthUser=$(promptInput "$(msg prompt_user)" "admin")
          isAuthPass=$(promptInput "$(msg prompt_password)" "admin")
          if [[ $SILENT_MODE -eq 0 ]]; then
            printf ' %s\n' "$(msg store_auth "$isAuthUser" "$isAuthPass" "${dirInstall}/accs.db")"
          fi
          echo -e "{\n  \"$isAuthUser\": \"$isAuthPass\"\n}" > "$dirInstall/accs.db"
        fi
      fi
    fi
  fi

  # Read-only database configuration
  if [[ -z "$isRdb" ]]; then
    if promptYesNo "$(msg enable_rdb)" "n" "n"; then
      isRdb=1
    else
      isRdb=0
    fi
  else
    # RDB setting exists, ask if user wants to change it
    if [[ $SILENT_MODE -eq 0 ]]; then
      local current_rdb_default
      current_rdb_default="$([[ $isRdb -eq 1 ]] && echo 'y' || echo 'n')"
      if promptYesNo "$(msg enable_rdb)" "$current_rdb_default" "n"; then
        isRdb=1
      else
        isRdb=0
      fi
    fi
  fi

  if [[ $isRdb -eq 1 ]] && [[ $SILENT_MODE -eq 0 ]]; then
    echo " $(msg set_readonly)"
    printf ' %s\n' "$(msg readonly_hint "$dirInstall/$serviceName.config")"
  fi

  # Logging configuration
  if [[ -z "$isLog" ]]; then
    if promptYesNo "$(msg enable_log)" "n" "y"; then
      isLog=1
    else
      isLog=0
    fi
  else
    # Log setting exists, ask if user wants to change it
    if [[ $SILENT_MODE -eq 0 ]]; then
      local current_log_default
      current_log_default="$([[ $isLog -eq 1 ]] && echo 'y' || echo 'n')"
      if promptYesNo "$(msg enable_log)" "$current_log_default" "y"; then
        isLog=1
      else
        isLog=0
      fi
    fi
  fi

  if [[ $isLog -eq 1 ]] && [[ $SILENT_MODE -eq 0 ]]; then
    printf ' - %s\n' "$(msg log_location "$dirInstall/$serviceName.log")"
  fi

  # BBR configuration
  if [[ -z "$isBbr" ]] && ! isBBRConfiguredInFile; then
    if promptYesNo "$(msg enable_bbr)" "n" "y"; then
      isBbr=1
    else
      isBbr=0
    fi
  fi

  # Build the complete config file with all options
  local daemon_options="--port $servicePort"

  if [[ $isRdb -eq 1 ]]; then
    daemon_options="$daemon_options --rdb"
  fi

  if [[ $isLog -eq 1 ]]; then
    daemon_options="$daemon_options --logpath $dirInstall/$serviceName.log"
  fi

  daemon_options="$daemon_options --path $dirInstall"

  if [[ $isAuth -eq 1 ]]; then
    daemon_options="$daemon_options --httpauth"
  fi

  cat << EOF > "$dirInstall/$serviceName.config"
DAEMON_OPTIONS="$daemon_options"
EOF
}

changeServiceUser() {
  local target_user="$1"
  if [[ -z "$target_user" ]]; then
    echo " $(msg error_username_required)"
    exit 1
  fi

  if [[ ! -d "$dirInstall" ]] || [[ ! -f "$dirInstall/$serviceName.config" ]]; then
    echo " - $(msg user_change_missing "$dirInstall")"
    exit 1
  fi

  checkArch

  local normalized_target
  normalized_target=$(echo "$target_user" | tr '[:upper:]' '[:lower:]')
  local default_lower
  default_lower=$(echo "$DEFAULT_USERNAME" | tr '[:upper:]' '[:lower:]')

  if [[ "$normalized_target" == "root" ]]; then
    target_user="root"
    USE_ROOT_USER=1
    username="root"
  elif [[ "$normalized_target" == "$default_lower" ]]; then
    target_user="$DEFAULT_USERNAME"
    USE_ROOT_USER=0
    username="$DEFAULT_USERNAME"
    if ! id "$username" >/dev/null 2>&1; then
      if ! addUser; then
        printf " - %s\n" "$(msg user_add_failed "$username")"
        exit 1
      fi
    fi
  else
    printf " - %s\n" "$(msg user_change_invalid "root" "$DEFAULT_USERNAME")"
    exit 1
  fi

  local owner="$username"
  local group
  if [[ "$username" == "root" ]]; then
    group="root"
  else
    group="$(id -gn "$username" 2>/dev/null || echo "$username")"
  fi

  createServiceFile
  sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.service"
  ln -sf "$dirInstall/$serviceName.service" /usr/local/lib/systemd/system/

  if [[ -d "$dirInstall" ]]; then
    chown -R "$owner":"$group" "$dirInstall"
    if [[ $SILENT_MODE -eq 0 ]]; then
      printf ' - %s\n' "$(msg user_change_permissions "$dirInstall" "$owner" "$group")"
    fi
  fi

  local restart_rc=0
  if ! systemctlCmd daemon-reload; then
    restart_rc=1
  fi
  if ! systemctlCmd restart "$serviceName.service"; then
    restart_rc=1
  fi

  if [[ $SILENT_MODE -eq 0 ]]; then
    printf ' - %s\n' "$(msg user_change_success "$username")"
    if [[ "$username" == "root" ]]; then
      echo " - $(msg running_as_root)"
    else
      printf ' - %s\n' "$(msg running_as_user "$username")"
    fi
    if [[ $restart_rc -eq 1 ]]; then
      echo " - $(colorize yellow "$(msg service_start_failed)")"
    fi
  else
    printf "%s\n" "$(msg user_change_success "$username")"
    if [[ $restart_rc -eq 1 ]]; then
      printf "%s\n" "$(msg service_start_failed)"
    fi
  fi
}

installTorrServer() {
  if [[ $SILENT_MODE -eq 0 && $ROOT_PROMPTED -eq 0 ]]; then
    if [[ $USE_ROOT_USER -ne 1 ]]; then
      if promptYesNo "$(msg prompt_run_as_root)" "n" "n"; then
        USE_ROOT_USER=1
        username="root"
      fi
    fi
    ROOT_PROMPTED=1
  fi

  if [[ $SILENT_MODE -eq 0 ]]; then
    echo " $(msg install_configure)"
  fi

  # Get target version and check glibc compatibility
  local target_version
  target_version=$(getTargetVersion)
  if [[ $SILENT_MODE -eq 0 ]]; then
    echo " - $(msg target_version) $target_version"
  fi

  if ! checkGlibcCompatibility "$target_version"; then
    exit 1
  fi

  # Check if already installed and up to date
  if checkInstalled; then
      if ! checkInstalledVersion; then
        if promptYesNo "$(msg want_update)" "y" "y"; then
          UpdateVersion
          return
        fi
      else
        # Already installed and up to date, allow reconfiguration
        if [[ $SILENT_MODE -eq 0 ]]; then
          echo " - $(msg running_as_user "$username")"
          echo ""
          # Allow user to reconfigure settings
          if promptYesNo "$(msg want_reconfigure)" "n" "n"; then
          # Read existing config first
          if [[ -f "$dirInstall/$serviceName.config" ]]; then
            readExistingConfig
          fi
          # Reconfigure service
          configureService
          # Configure BBR if enabled
          configureBBR
          # Update service file
          createServiceFile
          sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.service"
          sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.config"
          # Reload and restart service
          if ! systemctlCmd daemon-reload; then
            :
          fi
          if ! systemctlCmd restart "$serviceName.service"; then
            :
          fi
          echo ""
          echo " - $(msg config_updated)"
          echo ""
        fi
      fi
      return
    fi
  fi

  # Create directories
  if [[ ! -d "$dirInstall" ]]; then
    mkdir -p "$dirInstall"
  fi
  if [[ ! -d "/usr/local/lib/systemd/system" ]]; then
    mkdir -p "/usr/local/lib/systemd/system"
  fi

  # Download binary if needed
  local binName
  binName=$(getBinaryName)
  if [[ ! -f "$dirInstall/$binName" ]] || [[ ! -x "$dirInstall/$binName" ]] || [[ $(stat -c%s "$dirInstall/$binName" 2>/dev/null) -eq 0 ]]; then
    local urlBin
    if [[ -n "$specificVersion" ]]; then
      urlBin=$(buildDownloadUrl "$target_version" "$binName")
    else
      urlBin=$(buildDownloadUrl "latest" "$binName")
    fi
    downloadBinary "$urlBin" "$dirInstall/$binName" "$target_version"
  fi

  # Create service and config files
  createServiceFile
  configureService

  # Configure BBR if enabled (non-critical - always succeeds)
  configureBBR

  # Set up systemd service
  ln -sf "$dirInstall/$serviceName.service" /usr/local/lib/systemd/system/
  sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.service"
  sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.config"

  local service_started=0

  # Start service
  if [[ $SILENT_MODE -eq 0 ]]; then
    echo " $(msg starting_service)"
  fi
  if ! systemctlCmd daemon-reload; then
    :
  fi
  if ! systemctlCmd enable "$serviceName.service"; then
    :
  fi
  if systemctlCmd restart "$serviceName.service"; then
    service_started=1
  fi

  # Show completion message
  getIP
  local installed_version="$target_version"

  if [[ $SILENT_MODE -eq 0 ]]; then
    echo ""
    printf ' %s\n' "$(msg install_complete "$installed_version" "$dirInstall")"
    echo ""
    printf ' %s\n' "$(msg access_web "$serverIP" "$servicePort")"
    echo ""

    if [[ $isAuth -eq 1 && -n "$isAuthUser" ]]; then
      printf ' %s\n' "$(msg use_auth "$isAuthUser" "$isAuthPass")"
      echo ""
    fi

    if [[ $username == "root" ]]; then
      echo " $(colorize yellow "$(msg running_as_root)")"
    else
      printf ' %s\n' "$(msg running_as_user "$username")"
    fi

    if [[ $service_started -eq 0 ]]; then
      echo " $(colorize yellow "$(msg service_start_failed)")"
    fi
    echo ""
  fi

  if [[ $SILENT_MODE -eq 1 ]]; then
    printf "%s\n" "$(msg install_complete "$installed_version" "$dirInstall")"
    printf "%s\n" "$(msg access_web "$serverIP" "$servicePort")"
    if [[ $isAuth -eq 1 && -n "$isAuthUser" ]]; then
      printf "%s\n" "$(msg use_auth "$isAuthUser" "$isAuthPass")"
    fi
  fi

  return 0
}

# Common function to update/downgrade TorrServer version
updateTorrServerVersion() {
  local target_version="$1"
  local cancel_message="$2"
  local use_latest_url="${3:-0}"

  if ! checkGlibcCompatibility "$target_version"; then
    if [[ $SILENT_MODE -eq 0 ]]; then
      echo " - $(msg "$cancel_message")"
    fi
    return 1
  fi

  if ! systemctlCmd stop "$serviceName.service"; then
    :
  fi

  local binName
  binName=$(getBinaryName)
  local urlBin
  if [[ $use_latest_url -eq 1 && -z "$specificVersion" ]]; then
    urlBin=$(buildDownloadUrl "latest" "$binName")
  else
    urlBin=$(buildDownloadUrl "$target_version" "$binName")
  fi

  downloadBinary "$urlBin" "$dirInstall/$binName" "$target_version"

  # Update service file to reflect user change
  if [[ -f "$dirInstall/$serviceName.service" ]]; then
    createServiceFile
    if ! systemctlCmd daemon-reload; then
      :
    fi
  fi

  # Ensure BBR is active before starting service (if previously configured)
  ensureBBRActive

  if ! systemctlCmd start "$serviceName.service"; then
    :
  fi

  return 0
}

UpdateVersion() {
  local target_version
  target_version=$(getTargetVersion)
  updateTorrServerVersion "$target_version" "update_cancelled" 1
}

DowngradeVersion() {
  local target_version
  target_version=$(getVersionTag "$downgradeRelease")
  updateTorrServerVersion "$target_version" "downgrade_cancelled" 0
}

#############################################
#     CLEANUP FUNCTIONS
#############################################

cleanup() {
  if ! systemctlCmd --quiet stop "$serviceName"; then
    :
  fi
  if ! systemctlCmd --quiet disable "$serviceName"; then
    :
  fi
  rm -rf /usr/local/lib/systemd/system/"$serviceName.service" "$dirInstall" 2>/dev/null
  delUser
}

cleanAll() {
  if ! systemctlCmd --quiet stop torr; then
    :
  fi
  if ! systemctlCmd --quiet stop torrserver; then
    :
  fi
  if ! systemctlCmd --quiet disable torr; then
    :
  fi
  if ! systemctlCmd --quiet disable torrserver; then
    :
  fi
  rm -rf /home/torrserver 2>/dev/null
  rm -rf /usr/local/torr 2>/dev/null
  rm -rf /opt/torr* 2>/dev/null
  rm -f /{,etc,usr/local/lib}/systemd/system/tor{,r,rserver}.service 2>/dev/null
}

uninstall() {
  checkArch
  checkInstalled

  if [[ $SILENT_MODE -eq 1 ]]; then
    cleanup
    cleanAll
    echo " - $(msg uninstalled)"
    return
  fi

  echo ""
  echo " $(msg install_dir_label) ${dirInstall}"
  echo ""
  echo " $(msg uninstall_warning)"
  echo ""

  if promptYesNo "$(msg confirm_delete)" "n" "n"; then
    cleanup
    cleanAll
    echo " - $(msg uninstalled)"
    echo ""
  else
    echo ""
  fi
}

#############################################
#     RECONFIGURATION
#############################################

reconfigureTorrServer() {
  # Check if TorrServer is installed
  if ! checkInstalled; then
    echo " - $(msg not_found)"
    echo " - $(msg install_first_required "$scriptname")"
    exit 1
  fi

  # Set username based on USE_ROOT_USER flag
  if [[ $USE_ROOT_USER -eq 1 ]]; then
    username="root"
  fi

  if [[ $SILENT_MODE -eq 0 ]]; then
    echo " - $(msg running_as_user "$username")"
    echo ""
  fi

  # Read existing config first
  if [[ -f "$dirInstall/$serviceName.config" ]]; then
    readExistingConfig
  fi

  # Reconfigure service
  configureService

  # Configure BBR if enabled
  configureBBR

  # Update service file
  createServiceFile
  sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.service"
  sed -i 's/^[ \t]*//' "$dirInstall/$serviceName.config"

  # Reload and restart service
  if ! systemctlCmd daemon-reload; then
    :
  fi
  if ! systemctlCmd restart "$serviceName.service"; then
    :
  fi

  if [[ $SILENT_MODE -eq 0 ]]; then
    echo ""
    echo " - $(msg config_updated)"
    echo ""
  else
    echo " - $(msg config_updated)"
  fi
}

#############################################
#     HELP & MAIN
#############################################

helpUsage() {
  cat << EOF
$scriptname - TorrServer Installation Script

Usage: $scriptname [COMMAND] [OPTIONS]

Commands:
  -i, --install [VERSION]           Install latest or specific version
    install [VERSION]
  -u, --update                      Update to latest version
    update
  -c, --check                       Check for updates (version info only)
    check
  -d, --down VERSION                Downgrade to specific version
    down VERSION
  -r, --remove                      Uninstall TorrServer
    remove
  --reconfigure                     Reconfigure TorrServer settings
    reconfigure
  -C, --change-user USER            Change TorrServer service user (root|torrserver)
    change-user USER
  -h, --help                        Show this help message
    help

Options:
  --root                            Run service as root user
  --silent                          Non-interactive mode with defaults

Examples:
  # Install latest version interactively
  sudo $scriptname --install

  # Install specific version as root user silently
  sudo $scriptname --install 135 --root --silent

  # Update with silent mode
  sudo $scriptname --update --silent

  # Check for updates
  sudo $scriptname --check

  # Uninstall silently
  sudo $scriptname --remove --silent

  # Reconfigure TorrServer settings interactively
  sudo $scriptname --reconfigure

  # Switch service to run as root
  sudo $scriptname -C root

  # Switch service back to torrserver user
  sudo $scriptname --change-user torrserver

Default Settings (silent mode):
  - Port: ${portOverride:-$DEFAULT_PORT}
  - User: torrserver (or root with --root flag)
  - Auth: disabled
  - Read-only mode: disabled
  - Logging: disabled
  - BBR: enabled

EOF
}

parseArguments() {
  parsedCommand=""

  while [[ $# -gt 0 ]]; do
    case $1 in
      -i|--install|install)
        parsedCommand="install"
        shift
        # Check for version number
        if [[ $# -gt 0 ]]; then
          local next_arg="$1"
          if [[ "$next_arg" =~ ^[0-9]+$ ]]; then
            specificVersion="$next_arg"
            shift
          fi
        fi
        ;;
      -u|--update|update)
        parsedCommand="update"
        shift
        ;;
      -c|--check|check)
        parsedCommand="check"
        shift
        ;;
      -d|--down|down)
        parsedCommand="downgrade"
        shift
        if [[ $# -gt 0 ]]; then
          local next_arg="$1"
          if [[ "$next_arg" =~ ^[0-9]+$ ]]; then
            downgradeRelease="$next_arg"
            shift
          else
            echo " $(msg error_version_required)"
            echo " $(msg error_version_example "$scriptname")"
            exit 1
          fi
        else
          echo " $(msg error_version_required)"
          echo " $(msg error_version_example "$scriptname")"
          exit 1
        fi
        ;;
      -r|--remove|remove)
        parsedCommand="remove"
          shift
        ;;
      --reconfigure|reconfigure)
        parsedCommand="reconfigure"
        shift
        ;;
      -C|--change-user|change-user)
        parsedCommand="change_user"
        shift
        if [[ $# -gt 0 ]]; then
          changeUserName="$1"
          shift
        else
          echo " $(msg error_username_required)"
          exit 1
        fi
        ;;
      -h|--help|help)
        getLang  # Set language before showing help
        helpUsage
        exit 0
        ;;
      --root)
        USE_ROOT_USER=1
        shift
        ;;
      --silent)
        SILENT_MODE=1
        shift
        ;;
      *)
        echo " $(msg error_unknown_option "$1")"
        helpUsage
        exit 1
        ;;
    esac
  done
}

#############################################
#     MAIN EXECUTION
#############################################

main() {
  getLang

  parseArguments "$@"

  local command="$parsedCommand"

  case "$command" in
    install)
      if [[ $SILENT_MODE -eq 0 && -n "$specificVersion" ]]; then
        echo " - $(msg installing_specific_version "$specificVersion")"
      fi
      initialCheck

      if [[ $SILENT_MODE -eq 1 ]]; then
        servicePort="$DEFAULT_PORT"
        isAuth=0
        isRdb=0
        isLog=0
        isBbr=1
      fi

      if [[ $USE_ROOT_USER -eq 1 ]]; then
        username="root"
        if [[ $SILENT_MODE -eq 0 ]]; then
          echo " - $(msg running_as_root)"
        fi
      fi

      if ! checkInstalled; then
        installTorrServer
      else
        createServiceFile
        if ! systemctlCmd daemon-reload; then
          :
        fi
        if ! systemctlCmd stop "$serviceName.service"; then
          :
        fi
        if ! systemctlCmd start "$serviceName.service"; then
          :
        fi
        if [[ $SILENT_MODE -eq 0 ]]; then
          echo " - $(msg service_reconfigured_user "$username")"
        fi
      fi
      exit 0
      ;;
    update)
      initialCheck
      if [[ $USE_ROOT_USER -eq 1 ]]; then
        username="root"
      fi
      if checkInstalled; then
        if ! checkInstalledVersion; then
          UpdateVersion
        fi
      fi
      exit 0
      ;;
    check)
      initialCheck
      if checkInstalled; then
        checkInstalledVersion
      fi
      exit 0
      ;;
    downgrade)
      initialCheck
      if [[ $USE_ROOT_USER -eq 1 ]]; then
        username="root"
      fi
      if checkInstalled; then
        DowngradeVersion
      fi
      exit 0
      ;;
    remove)
      uninstall
      exit 0
      ;;
    reconfigure)
      initialCheck
      if [[ $USE_ROOT_USER -eq 1 ]]; then
        username="root"
      fi
      reconfigureTorrServer
      exit 0
      ;;
    change_user)
      if [[ -z "$changeUserName" ]]; then
        echo " $(msg error_username_required)"
        exit 1
      fi
      if ! isRoot; then
        echo " $(msg need_root)"
        exit 1
      fi
      changeServiceUser "$changeUserName"
      exit 0
      ;;
  esac

  # Interactive mode if no command provided and not silent
  if [[ $SILENT_MODE -eq 0 ]]; then
    echo ""
    echo " $(msg lang_choice)"
    echo " [$(colorize green 1)] $(msg lang_english)"
    echo " [$(colorize yellow 2)] $(msg lang_russian)"
    local answer_lang
    answer_lang=$(promptInput "$(msg your_lang)" "1")
    if [[ "$answer_lang" == "2" ]]; then
      lang="ru"
    fi

    echo ""
    echo "============================================================="
    echo " $(msg script_title)"
    echo "============================================================="
    echo ""

    local user_choice
    user_choice=$(promptYesNoDelete "$(msg want_install)" "n" "y")

    if [[ "$user_choice" == "delete" ]]; then
      initialCheck
      uninstall
    elif [[ "$user_choice" == "yes" ]]; then
      initialCheck

      if promptYesNo "$(msg prompt_run_as_root)" "n" "n"; then
        USE_ROOT_USER=1
        username="root"
      fi
      ROOT_PROMPTED=1

      installTorrServer
    fi
  fi

  echo " $(msg have_fun)"
  echo ""
}

# Run main function
main "$@"
