#!/usr/bin/env bash

# RagLeap Self-Hosted Installer v1.0.0
# Usage: curl -sSL https://install.ragleap.com/install.sh | bash
#        OR:   bash <(curl -sSL https://install.ragleap.com/install.sh)
#        OR:   wget -qO- https://install.ragleap.com/install.sh | bash

RAGLEAP_VERSION="1.0.0"
INSTALL_DIR="${HOME}/ragleap"
ENV_FILE="$INSTALL_DIR/.env"

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

log()   { echo -e "${GREEN}[OK]${NC} $*"; }
info()  { echo -e "${BLUE}[->]${NC} $*"; }
warn()  { echo -e "${YELLOW}[!]${NC} $*"; }
error() { echo -e "${RED}[X]${NC} $*"; exit 1; }

banner() {
  clear 2>/dev/null || true
  echo -e "${CYAN}"
  echo "  ██████╗  █████╗  ██████╗ ██╗     ███████╗ █████╗ ██████╗ "
  echo "  ██╔══██╗██╔══██╗██╔════╝ ██║     ██╔════╝██╔══██╗██╔══██╗"
  echo "  ██████╔╝███████║██║  ███╗██║     █████╗  ███████║██████╔╝"
  echo "  ██╔══██╗██╔══██║██║   ██║██║     ██╔══╝  ██╔══██║██╔═══╝ "
  echo "  ██║  ██║██║  ██║╚██████╔╝███████╗███████╗██║  ██║██║     "
  echo "  ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚═╝  ╚═╝╚═╝     "
  echo -e "${NC}"
  echo -e "  ${BOLD}Self-Hosted Installer v${RAGLEAP_VERSION}${NC}"
  echo -e "  ${BLUE}https://ragleap.com${NC}"
  echo ""
}

ask_input() {
  local prompt="$1"
  local default="$2"
  local result=""
  if [ -n "$default" ]; then
    echo -e "${CYAN}[?]${NC} ${prompt} [${default}]: " >&2
  else
    echo -e "${CYAN}[?]${NC} ${prompt}: " >&2
  fi
  read -r result </dev/stdin
  if [ -z "$result" ] && [ -n "$default" ]; then
    result="$default"
  fi
  echo "$result"
}

gen_secret() {
  python3 -c "import secrets,string; c=string.ascii_letters+string.digits; print(''.join(secrets.choice(c) for _ in range(32)))"
}

preflight() {
  echo -e "\n${BOLD}${BLUE}-- Pre-flight Checks --${NC}\n"
  command -v docker &>/dev/null || error "Docker not found. Install from https://docs.docker.com/get-docker/"
  command -v curl   &>/dev/null || error "curl not found. Run: sudo apt-get install curl"
  command -v python3 &>/dev/null || error "python3 not found."
  docker info &>/dev/null || error "Docker daemon not running. Run: sudo service docker start"
  log "Pre-flight checks passed"
}

get_input() {
  echo -e "\n${BOLD}${BLUE}-- Configuration --${NC}\n"
  echo -e "${BOLD}Answer the questions below. Press ENTER to accept defaults.${NC}\n"

  echo -e "${CYAN}[?]${NC} License key (RAGL-XXXX or FREE for free plan):"
  read -r LICENSE_KEY
  LICENSE_KEY=$(echo "${LICENSE_KEY:-FREE}" | tr '[:lower:]' '[:upper:]' | xargs)
  if [ "$LICENSE_KEY" = "FREE" ]; then
    LICENSE_KEY="FREE-PLAN"
    log "Free plan selected"
  else
    log "License: $LICENSE_KEY"
  fi


  echo ""
  echo -e "  ${BLUE}Options:${NC}"
  echo -e "    localhost       -> your machine only"
  echo -e "    45.12.34.56     -> VPS with IP (no domain needed)"
  echo -e "    app.example.com -> domain with auto SSL"
  echo ""
  echo -e "${CYAN}[?]${NC} Enter IP, domain, or press ENTER for localhost:"
  read -r DOMAIN
  DOMAIN="${DOMAIN:-localhost}"

  if echo "$DOMAIN" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$"; then
    SITE_URL="http://${DOMAIN}"
    log "IP address - HTTP mode"
    HOST_IP="$DOMAIN"
  elif [ "$DOMAIN" = "localhost" ]; then
    SITE_URL="http://localhost"
    log "Localhost - HTTP mode"
    HOST_IP=$(hostname -I | awk '{print $1}' | tr -d " ")
    [ -z "$HOST_IP" ] && HOST_IP="127.0.0.1"
    log "Machine IP: $HOST_IP"
  else
    SITE_URL="https://${DOMAIN}"
    log "Domain detected - HTTPS with SSL"
    HOST_IP="$DOMAIN"
  fi


  echo -e "${CYAN}[?]${NC} Admin email (press ENTER for default):"
  read -r ADMIN_EMAIL
  ADMIN_EMAIL="${ADMIN_EMAIL:-admin@${DOMAIN}}"
  [ "$DOMAIN" = "localhost" ] && SITE_URL="http://localhost"

  DB_PASS=$(gen_secret)
  REDIS_PASS=$(gen_secret)
  NEO4J_PASS=$(gen_secret)
  DJANGO_SECRET=$(gen_secret)$(gen_secret)
}

write_env() {
  echo -e "\n${BOLD}${BLUE}-- Writing Configuration --${NC}\n"
  mkdir -p "$INSTALL_DIR"
  tee "$ENV_FILE" > /dev/null <<ENVEOF
RAGLEAP_LICENSE_KEY=${LICENSE_KEY}
RAGLEAP_DOMAIN=${DOMAIN}
RAGLEAP_VERSION=${RAGLEAP_VERSION}
SECRET_KEY=${DJANGO_SECRET}
DEBUG=False
ALLOWED_HOSTS=${DOMAIN},localhost,127.0.0.1,${HOST_IP}
SITE_URL=${SITE_URL}
ADMIN_EMAIL=${ADMIN_EMAIL}
SELF_HOSTED=true
TRANSFORMERS_OFFLINE=1
HF_DATASETS_OFFLINE=1
SENTENCE_TRANSFORMERS_HOME=/tmp/st_cache
DATABASE_URL=postgresql://ragleap:${DB_PASS}@postgres:5432/ragleap
POSTGRES_DB=ragleap
POSTGRES_USER=ragleap
POSTGRES_PASSWORD=${DB_PASS}
REDIS_URL=redis://:${REDIS_PASS}@redis:6379/0
CELERY_BROKER_URL=redis://:${REDIS_PASS}@redis:6379/0
REDIS_PASSWORD=${REDIS_PASS}
REDIS_CACHE_URL=redis://:${REDIS_PASS}@redis:6379/1
ACCOUNT_EMAIL_VERIFICATION=none
SECURE_SSL_REDIRECT=False
NEO4J_URI=bolt://neo4j:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=${NEO4J_PASS}
EMAIL_HOST=smtp-relay.brevo.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
BREVO_API_KEY=${BREVO_KEY}
DEFAULT_FROM_EMAIL=noreply@${DOMAIN}
TRANSFORMERS_OFFLINE=1
HF_DATASETS_OFFLINE=1
SENTENCE_TRANSFORMERS_HOME=/tmp/st_cache
ENVEOF
  chmod 600 "$ENV_FILE"
  log ".env written to $ENV_FILE"
}

deploy() {
  echo -e "\n${BOLD}${BLUE}-- Deploying Services --${NC}\n"

  info "Downloading config files..."
  curl -sSL https://install.ragleap.com/docker-compose.selfhost.yml \
    -o "$INSTALL_DIR/docker-compose.yml"
  curl -sSL https://install.ragleap.com/nginx_default.conf \
    -o "$INSTALL_DIR/nginx_default.conf"
  curl -sSL https://install.ragleap.com/pg_hba.conf \
    -o "$INSTALL_DIR/pg_hba.conf"

  mkdir -p "$INSTALL_DIR/docker/postgres"
  curl -sSL https://install.ragleap.com/docker/postgres/init.sql \
    -o "$INSTALL_DIR/docker/postgres/init.sql" 2>/dev/null || true

  cd "$INSTALL_DIR"

  info "Pulling Docker images (3-5 minutes first time)..."
  docker compose pull

  info "Starting services..."
  docker compose up -d

  info "Waiting for PostgreSQL to be ready..."
  local retries=30
  until docker compose exec -T postgres pg_isready -U ragleap &>/dev/null; do
    retries=$((retries-1))
    [ $retries -le 0 ] && error "PostgreSQL failed to start. Run: docker compose logs postgres"
    echo -n "."
    sleep 3
  done
  echo ""
  log "PostgreSQL ready"

  info "Running database migrations..."
  if ! docker compose exec -T backend python manage.py migrate --noinput >/dev/null 2>&1; then
    docker compose exec -T backend python manage.py migrate api 0052_leadcapture_and_more --fake >/dev/null 2>&1 || true
    docker compose exec -T backend python manage.py migrate --noinput >/dev/null 2>&1 || true
  fi
  log "Migrations applied"

  info "Collecting static files..."
  docker compose exec -T backend python manage.py collectstatic --noinput --clear >/dev/null 2>&1

  info "Creating admin account..."
  ADMIN_PASS=$(gen_secret | head -c 16)
  docker compose exec -T backend python manage.py shell -c "
from django.contrib.auth import get_user_model
from allauth.account.models import EmailAddress
User = get_user_model()
email = '${ADMIN_EMAIL}'
if not User.objects.filter(email=email).exists():
    u = User.objects.create_superuser(email, email, '${ADMIN_PASS}')
else:
    u = User.objects.get(email=email)
ea, _ = EmailAddress.objects.get_or_create(user=u, email=email)
ea.verified = True; ea.primary = True; ea.save()
" >/dev/null 2>&1 || true
  log "Admin account ready"
}

summary() {
  echo ""
  echo -e "${GREEN}${BOLD}╔══════════════════════════════════════╗${NC}"
  echo -e "${GREEN}${BOLD}║   RagLeap installed successfully!    ║${NC}"
  echo -e "${GREEN}${BOLD}╚══════════════════════════════════════╝${NC}"
  echo ""
  echo -e "  ${BOLD}App URL:${NC}       ${CYAN}${SITE_URL}${NC}"
  echo -e "  ${BOLD}Admin Panel:${NC}   ${CYAN}${SITE_URL}/selfhost/admin/${NC}"
  echo -e "  ${BOLD}Django Admin:${NC}  ${CYAN}${SITE_URL}/admin/${NC}"
  echo ""
  echo -e "  ${BOLD}Admin Email:${NC}    ${ADMIN_EMAIL}"
  echo -e "  ${BOLD}Admin Password:${NC} ${YELLOW}${ADMIN_PASS}${NC}"
  echo ""
  warn "Save your admin password — it won't be shown again!"
  echo ""
  echo -e "${BOLD}Useful commands:${NC}"
  echo -e "  View logs:  ${CYAN}docker compose -f $INSTALL_DIR/docker-compose.yml logs -f${NC}"
  echo -e "  Stop:       ${CYAN}docker compose -f $INSTALL_DIR/docker-compose.yml down${NC}"
  echo -e "  Update:     ${CYAN}curl -sSL https://install.ragleap.com/install.sh | bash upgrade${NC}"
  echo ""
  echo -e "  ${BOLD}Docs:${NC} https://docs.ragleap.com/self-hosted/installation/"
  echo ""
  echo -e "${BOLD}User Management:${NC}"
  echo -e "  List users:      ${CYAN}ragleap users${NC}"
  echo -e "  Reset password:  ${CYAN}ragleap reset-password user@example.com${NC}"
  echo -e "  Change email:    ${CYAN}ragleap change-email old@email.com new@email.com${NC}"
  echo ""
  echo -e "${BOLD}Next steps:${NC}"
  echo -e "  1. Open ${CYAN}${SITE_URL}${NC} in your browser"
  echo -e "  2. Login with your admin credentials"
  echo -e "  3. Go to ${CYAN}Settings -> AI Settings${NC} to connect your AI provider"
  echo -e "     Add your preferred AI key: Gemini (free) / Anthropic / OpenAI"
  echo ""
  echo ""
}

upgrade() {
  echo -e "\n${BOLD}${BLUE}-- Upgrading RagLeap --${NC}\n"
  [ -f "$ENV_FILE" ] || error "No installation found at $INSTALL_DIR"
  cd "$INSTALL_DIR"
  info "Pulling latest images..."
  docker compose pull
  info "Restarting services..."
  docker compose up -d
  info "Running migrations..."
  docker compose exec -T backend python manage.py migrate --noinput
  log "Upgrade complete!"
}

# ── Main ──────────────────────────────────────────────────────
case "${1:-install}" in
  install)
    banner
    preflight
    get_input
    write_env
    deploy
    summary
    ;;
  upgrade)
    upgrade
    ;;
  *)
    echo "Usage: $0 [install|upgrade]"
    ;;
esac
