#!/bin/bash
set -euo pipefail

PKG_NAME="line-monit-back"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
APP_DIR="/opt/${PKG_NAME}"
RESET_PASSWORD_SCRIPT="${APP_DIR}/scripts/reset-password.js"
DB_NAME="appdbv2"
DB_USER="appuser"
BACKUP_DIR="/var/backups/${PKG_NAME}"

require_root() {
  if [ "$(id -u)" -ne 0 ]; then
    echo "Run as root." >&2
    exit 1
  fi
}

latest_deb() {
  find "$SCRIPT_DIR" -maxdepth 1 -type f -name "${PKG_NAME}_*.deb" | sort -V | tail -n 1
}

prompt_deb_path() {
  local default_path=""
  default_path="$(latest_deb || true)"

  if [ -n "$default_path" ]; then
    read -r -p "Path to .deb [${default_path}]: " deb_path
    deb_path="${deb_path:-$default_path}"
  else
    read -r -p "Path to .deb: " deb_path
  fi

  if [ ! -f "$deb_path" ]; then
    echo "Package not found: $deb_path" >&2
    return 1
  fi

  printf '%s\n' "$deb_path"
}

install_or_update() {
  local action_label="$1"
  local deb_path=""

  require_root
  deb_path="$(prompt_deb_path)"

  echo "${action_label}: $deb_path"
  chmod o+r "$deb_path"
  apt-get update
  apt-get install -y --allow-downgrades "$deb_path"
}

is_installed() {
  dpkg -s "$PKG_NAME" >/dev/null 2>&1
}

run_as_postgres() {
  local command="$1"

  if id postgres >/dev/null 2>&1; then
    su -s /bin/sh postgres -c "$command" 2>/dev/null || true
  fi
}

remove_everything() {
  require_root

  if ! is_installed; then
    echo "${PKG_NAME} is not installed."
    return 0
  fi

  echo "This will fully remove ${PKG_NAME}, config, frontend and PostgreSQL data."
  read -r -p "Type DELETE to continue: " confirm
  if [ "$confirm" != "DELETE" ]; then
    echo "Cancelled."
    return 0
  fi

  systemctl stop ${PKG_NAME}.service 2>/dev/null || true
  systemctl disable ${PKG_NAME}.service 2>/dev/null || true

  apt-get purge -y ${PKG_NAME} 2>/dev/null || dpkg --purge ${PKG_NAME} 2>/dev/null || true

  rm -f /etc/nginx/sites-enabled/${PKG_NAME}
  rm -f /etc/nginx/sites-enabled/default
  rm -f /etc/nginx/sites-available/${PKG_NAME}
  nginx -t 2>/dev/null && systemctl reload nginx || true

  rm -rf "/opt/${PKG_NAME}"
  rm -rf "/etc/${PKG_NAME}"
  rm -rf "/var/www/${PKG_NAME}"

  run_as_postgres "psql -d postgres -c \"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'appdbv2' AND pid <> pg_backend_pid();\""
  run_as_postgres "psql -c \"DROP DATABASE IF EXISTS appdbv2;\""
  run_as_postgres "psql -c \"DROP ROLE IF EXISTS appuser;\""

  id -u linemonit >/dev/null 2>&1 && deluser --system linemonit 2>/dev/null || true
  getent group linemonit >/dev/null 2>&1 && delgroup --system linemonit 2>/dev/null || true

  systemctl daemon-reload
  echo "${PKG_NAME} removed."
}

reset_password() {
  local email=""
  local password=""
  local password_confirm=""

  require_root

  if [ ! -f "$RESET_PASSWORD_SCRIPT" ]; then
    echo "Password reset helper not found: $RESET_PASSWORD_SCRIPT" >&2
    echo "Install the package first." >&2
    return 1
  fi

  if ! is_installed; then
    echo "${PKG_NAME} is not installed." >&2
    return 1
  fi

  if ! command -v node >/dev/null 2>&1; then
    echo "node is not installed." >&2
    return 1
  fi

  read -r -p "Superadmin email: " email
  if [ -z "$email" ]; then
    echo "Email is required." >&2
    return 1
  fi

  read -r -s -p "Password: " password
  echo ""
  read -r -s -p "Repeat password: " password_confirm
  echo ""

  if [ -z "$password" ]; then
    echo "Password is required." >&2
    return 1
  fi

  if [ "$password" != "$password_confirm" ]; then
    echo "Passwords do not match." >&2
    return 1
  fi

  node "$RESET_PASSWORD_SCRIPT" --email "$email" --password "$password"
}

latest_dump() {
  find "$BACKUP_DIR" -maxdepth 1 -type f -name "${DB_NAME}_*.dump" 2>/dev/null | sort -V | tail -n 1
}

prompt_dump_path() {
  local dumps=()
  local default_path=""
  local choice=""
  local dump_path=""

  if [ -d "$BACKUP_DIR" ]; then
    while IFS= read -r line; do
      [ -n "$line" ] && dumps+=("$line")
    done < <(find "$BACKUP_DIR" -maxdepth 1 -type f -name "${DB_NAME}_*.dump" 2>/dev/null | sort -V)
  fi

  if [ "${#dumps[@]}" -gt 0 ]; then
    echo "Available backups in ${BACKUP_DIR}:" >&2
    local i=1
    for d in "${dumps[@]}"; do
      printf '  %2d) %s (%s)\n' "$i" "$(basename "$d")" "$(du -h "$d" | cut -f1)" >&2
      i=$((i + 1))
    done
    default_path="$(latest_dump)"
    read -r -p "Choose number or enter full path [${default_path}]: " choice
    if [ -z "$choice" ]; then
      dump_path="$default_path"
    elif [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#dumps[@]}" ]; then
      dump_path="${dumps[$((choice - 1))]}"
    else
      dump_path="$choice"
    fi
  else
    echo "No backups found in ${BACKUP_DIR}." >&2
    read -r -p "Path to .dump: " dump_path
  fi

  if [ -z "$dump_path" ] || [ ! -f "$dump_path" ]; then
    echo "Dump not found: $dump_path" >&2
    return 1
  fi

  printf '%s\n' "$dump_path"
}

restore_backup() {
  local dump_path=""
  local confirm=""

  require_root

  if ! command -v pg_restore >/dev/null 2>&1; then
    echo "pg_restore not found." >&2
    return 1
  fi

  if ! sudo -u postgres psql -c '\q' 2>/dev/null; then
    echo "PostgreSQL is not available." >&2
    return 1
  fi

  dump_path="$(prompt_dump_path)" || return 1

  echo ""
  echo "This will OVERWRITE database '${DB_NAME}' with:"
  echo "  $dump_path"
  echo "All current data will be lost."
  read -r -p "Type RESTORE to continue: " confirm
  if [ "$confirm" != "RESTORE" ]; then
    echo "Cancelled."
    return 0
  fi

  echo "Stopping ${PKG_NAME}.service..."
  systemctl stop "${PKG_NAME}.service" 2>/dev/null || true

  echo "Closing active database connections..."
  sudo -u postgres psql -d postgres -c \
    "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${DB_NAME}' AND pid <> pg_backend_pid();" \
    >/dev/null 2>&1 || true

  echo "Recreating database '${DB_NAME}'..."
  if ! sudo -u postgres psql -d postgres -c "DROP DATABASE IF EXISTS ${DB_NAME};" >/dev/null 2>&1; then
    echo "Failed to drop database ${DB_NAME}." >&2
    systemctl start "${PKG_NAME}.service" 2>/dev/null || true
    return 1
  fi
  if ! sudo -u postgres createdb -O "${DB_USER}" "${DB_NAME}" >/dev/null 2>&1; then
    echo "Failed to create database ${DB_NAME}." >&2
    return 1
  fi

  echo "Restoring from backup..."
  if sudo -u postgres pg_restore -d "${DB_NAME}" "$dump_path"; then
    echo "Restore completed."
  else
    echo "⚠️  pg_restore reported errors. Review the output above." >&2
  fi

  echo "Starting ${PKG_NAME}.service..."
  systemctl start "${PKG_NAME}.service" 2>/dev/null || true
  echo "Done."
}

show_menu() {
  PS3="Choose action: "
  select action in "Установить" "Обновить" "Удалить" "Сбросить пароль" "Восстановить из бэкапа" "Выход"; do
    case "$action" in
      "Установить")
        install_or_update "Installing"
        break
        ;;
      "Обновить")
        install_or_update "Updating"
        break
        ;;
      "Удалить")
        remove_everything
        break
        ;;
      "Сбросить пароль")
        reset_password
        break
        ;;
      "Восстановить из бэкапа")
        restore_backup
        break
        ;;
      "Выход")
        break
        ;;
      *)
        echo "Unknown option"
        ;;
    esac
  done
}

show_menu