#!/usr/bin/env bash
set -euo pipefail

IONIDE_BOT_IMAGE="${IONIDE_BOT_IMAGE:-registry.ionide.net/ionide-bot:latest}"
IONIDE_REGISTRY_PULL_USER="${IONIDE_REGISTRY_PULL_USER:-ionide-public}"
IONIDE_REGISTRY_PULL_PASSWORD="${IONIDE_REGISTRY_PULL_PASSWORD:-ionide-bot-pull-only}"
CONTAINER_NAME="ionide-discord-bot"

INSTALL_DIR="${IONIDE_BOT_INSTALL_DIR:-$PWD/ionide-bot}"
RECONFIGURE=false
if [[ "${1:-}" == "--reconfigure" ]]; then
  RECONFIGURE=true
fi

log() { printf '%s\n' "$*"; }
die() { printf 'Error: %s\n' "$*" >&2; exit 1; }

prompt() {
  local __var="$2"
  [[ -r /dev/tty ]] || die "This needs an interactive terminal to prompt for input, but none is available. Run it in a real terminal: bash install.sh"
  read -rp "$1" "$__var" < /dev/tty
}

cat <<'BANNER'
██╗ ██████╗ ███╗   ██╗██╗██████╗ ███████╗
██║██╔═══██╗████╗  ██║██║██╔══██╗██╔════╝
██║██║   ██║██╔██╗ ██║██║██║  ██║█████╗
██║██║   ██║██║╚██╗██║██║██║  ██║██╔══╝
██║╚██████╔╝██║ ╚████║██║██████╔╝███████╗
╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝╚═════╝ ╚══════╝
BANNER
log ""

docker_ready() {
  command -v docker >/dev/null 2>&1
}

if ! docker_ready; then
  log "Docker was not found."
  prompt "Install Docker now? [y/N]: " INSTALL_DOCKER
  if [[ "$INSTALL_DOCKER" =~ ^[Yy]$ ]]; then
    log "Installing Docker via the official convenience script (https://get.docker.com)..."
    if [[ "$(id -u)" -eq 0 ]]; then
      curl -fsSL https://get.docker.com | sh
    else
      command -v sudo >/dev/null 2>&1 || die "Docker install needs root and 'sudo' isn't available. Re-run this script as root."
      curl -fsSL https://get.docker.com | sudo sh
    fi
    docker_ready || die "Docker install finished but 'docker' still isn't available. Install manually: https://docs.docker.com/engine/install/"
    log "Docker installed successfully."
  else
    die "Docker is required. Install it manually: https://docs.docker.com/engine/install/"
  fi
fi

if ! docker info >/dev/null 2>&1; then
  if [[ "$(id -u)" -eq 0 ]]; then
    die "Docker is installed, but the daemon isn't reachable even as root — is the service running? Try: sudo systemctl start docker"
  fi
  die "Docker is installed, but this user can't reach its daemon (not in the 'docker' group yet). Either re-run this script with sudo (curl -fsSL https://install.ionide.net | sudo bash), or run 'sudo usermod -aG docker \"\$USER\"' and log back in before trying again."
fi

command -v openssl >/dev/null 2>&1 || die "openssl is required but not found. Needed to generate the bot's secrets-encryption key."

mkdir -p "$INSTALL_DIR/bot-data"
chmod 777 "$INSTALL_DIR/bot-data"
cd "$INSTALL_DIR"

ENV_FILE="$INSTALL_DIR/.env"

if [[ -f "$ENV_FILE" && "$RECONFIGURE" == "false" ]]; then
  log "Existing install found at $INSTALL_DIR — skipping setup, pulling the latest image."
  BOT_TOKEN="$(grep -m1 '^BOT_TOKEN=' "$ENV_FILE" | cut -d= -f2-)"
else
  log "Setting up ionide-bot in $INSTALL_DIR"
  log ""
  log "You'll need a Discord bot application first (if you don't have one yet):"
  log "  1. https://discord.com/developers/applications -> New Application"
  log "  2. Bot tab -> Reset Token -> copy it"
  log ""

  prompt "Discord bot token: " BOT_TOKEN
  [[ -n "$BOT_TOKEN" ]] || die "A Discord bot token is required."

  SECRETS_ENCRYPTION_KEY="$(openssl rand -hex 32)"

  cat > "$ENV_FILE" <<EOF
BOT_TOKEN=${BOT_TOKEN}

SECRETS_ENCRYPTION_KEY=${SECRETS_ENCRYPTION_KEY}
EOF

  log ""
  log ".env written to $ENV_FILE"
fi

docker login -u "$IONIDE_REGISTRY_PULL_USER" --password-stdin "${IONIDE_BOT_IMAGE%%/*}" <<<"$IONIDE_REGISTRY_PULL_PASSWORD" >/dev/null

log "Pulling ${IONIDE_BOT_IMAGE}..."
docker pull "$IONIDE_BOT_IMAGE"

if docker inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
  log "Removing existing container..."
  docker rm -f "$CONTAINER_NAME" >/dev/null
fi

docker run -d \
  --name "$CONTAINER_NAME" \
  --restart unless-stopped \
  --memory=768m \
  --env-file "$ENV_FILE" \
  -v "$INSTALL_DIR/bot-data:/app/data" \
  "$IONIDE_BOT_IMAGE" >/dev/null

READY_MARKER="Discord bot started."
STARTED=false
for _ in $(seq 1 45); do
  if docker logs "$CONTAINER_NAME" 2>/dev/null | grep -qF "$READY_MARKER"; then
    STARTED=true
    break
  fi
  STATUS="$(docker inspect -f '{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null || true)"
  if [[ "$STATUS" == "exited" || "$STATUS" == "restarting" ]]; then
    break
  fi
  sleep 1
done

if [[ "$STARTED" != "true" ]]; then
  log ""
  log "The bot did not report a successful startup. Recent logs:"
  docker logs --tail 30 "$CONTAINER_NAME" || true
  die "Install failed — the container is not running correctly. Check the token and logs above, then re-run with --reconfigure."
fi

CLIENT_ID_SEGMENT="${BOT_TOKEN%%.*}"
PAD=$(( (4 - ${#CLIENT_ID_SEGMENT} % 4) % 4 ))
CLIENT_ID_PADDING=""
if [[ "$PAD" -gt 0 ]]; then
  CLIENT_ID_PADDING="$(printf '=%.0s' $(seq 1 "$PAD"))"
fi
CLIENT_ID_PADDED="${CLIENT_ID_SEGMENT}${CLIENT_ID_PADDING}"
CLIENT_ID="$(printf '%s' "$CLIENT_ID_PADDED" | base64 -d 2>/dev/null || true)"

log ""
log "ionide-bot is running."
log ""
if [[ "$CLIENT_ID" =~ ^[0-9]+$ ]]; then
  log "Invite it to your server:"
  log "  https://discord.com/oauth2/authorize?client_id=${CLIENT_ID}&scope=bot+applications.commands&permissions=93184"
else
  log "Could not derive an invite link from the token automatically."
  log "Find your Application ID at https://discord.com/developers/applications and use:"
  log "  https://discord.com/oauth2/authorize?client_id=<your-application-id>&scope=bot+applications.commands&permissions=93184"
fi
log ""
log "Next steps:"
log "  1. Invite the bot using the URL above."
log "  2. In whichever channel you want as the command center, run: /activate <your license key>"
log "  3. Once activated, you're the bot owner — see /secrets-set to add exchange API credentials."
