#!/usr/bin/env bash
# =============================================================================
# COCONEWS - Instalacion de prerequisites en Debian 12 / Ubuntu 22.04+
# Ejecutar ANTES de install.sh
# Uso: sudo bash prerequisites.sh
# =============================================================================
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info()  { echo -e "${GREEN}[OK]${NC}    $*"; }
step()  { echo -e "${BLUE}[-->]${NC}   $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

[[ "$EUID" -ne 0 ]] && error "Ejecutar como root: sudo bash prerequisites.sh"

# Detectar OS
if [[ -f /etc/os-release ]]; then
    . /etc/os-release
    OS_ID="$ID"
    OS_VER="$VERSION_ID"
else
    error "No se puede detectar el sistema operativo"
fi

[[ "$OS_ID" == "debian" || "$OS_ID" == "ubuntu" ]] || \
    error "Solo soportado en Debian/Ubuntu. Detectado: $OS_ID"

echo ""
echo "================================================="
echo "  COCONEWS - Instalador de Prerequisites"
echo "  OS: $PRETTY_NAME"
echo "================================================="
echo ""

# =============================================================================
# 1. PAQUETES APT BASE
# =============================================================================
# Comprobar espacio en disco (mínimo 10 GB libres)
DISK_FREE_GB=$(df / --output=avail -BG | tail -1 | tr -d 'G ')
if [[ "${DISK_FREE_GB:-0}" -lt 10 ]]; then
    warn "Espacio libre en disco: ${DISK_FREE_GB} GB (recomendado mínimo 10 GB)"
    warn "Los modelos ML necesitan ~5 GB. Continua bajo tu responsabilidad."
fi

step "Actualizando repositorios apt..."
apt-get update -qq 2>/tmp/apt-update.log || {
    echo -e "${RED}Error al actualizar repositorios apt.${NC}"
    echo "  Posibles causas:"
    echo "    • Sin conexión a internet"
    echo "    • Repositorios con errores: cat /tmp/apt-update.log"
    echo "    • Solución: apt-get update --fix-missing"
    exit 1
}

step "Instalando paquetes del sistema..."
apt-get install -y --no-install-recommends \
    curl wget git build-essential \
    ca-certificates gnupg lsb-release \
    software-properties-common apt-transport-https \
    tzdata locales \
    rsync \
    openssl \
    libpq-dev \
    libssl-dev \
    libffi-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    zlib1g-dev
info "Paquetes base instalados"

# =============================================================================
# 2. POSTGRESQL 16
# =============================================================================
step "Instalando PostgreSQL 16..."
if ! command -v psql &>/dev/null; then
    # Repositorio oficial de PostgreSQL
    install -d /usr/share/postgresql-common/pgdg
    curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
        | gpg --dearmor -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg
    echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg] \
https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
        > /etc/apt/sources.list.d/pgdg.list
    apt-get update -qq
    apt-get install -y postgresql-16 postgresql-client-16
fi
info "PostgreSQL: $(psql --version)"

# =============================================================================
# 3. REDIS
# =============================================================================
step "Instalando Redis..."
if ! command -v redis-server &>/dev/null; then
    apt-get install -y redis-server
fi
info "Redis: $(redis-server --version | cut -d' ' -f3)"

# =============================================================================
# 4. NGINX
# =============================================================================
step "Instalando Nginx..."
if ! command -v nginx &>/dev/null; then
    apt-get install -y nginx
fi
info "Nginx: $(nginx -v 2>&1 | cut -d'/' -f2)"

# =============================================================================
# 5. PYTHON 3 + pip + venv
# =============================================================================
step "Instalando Python 3..."
apt-get install -y python3 python3-pip python3-venv python3-dev
info "Python: $(python3 --version)"

# =============================================================================
# 6. NODE.JS 20 LTS
# =============================================================================
step "Instalando Node.js 20 LTS..."
if ! command -v node &>/dev/null || [[ "$(node -v | tr -d 'v' | cut -d. -f1)" -lt 18 ]]; then
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
    apt-get install -y nodejs
fi
info "Node.js: $(node --version) | npm: $(npm --version)"

# =============================================================================
# 7. GO 1.25
# =============================================================================
step "Instalando Go 1.25..."
GO_VERSION="1.25.0"
INSTALLED_GO=$(go version 2>/dev/null | awk '{print $3}' | tr -d 'go' || echo "0")

# Comparar version instalada
needs_go=false
if ! command -v go &>/dev/null; then
    needs_go=true
else
    IFS='.' read -ra INS <<< "$INSTALLED_GO"
    IFS='.' read -ra REQ <<< "$GO_VERSION"
    if [[ "${INS[0]}" -lt "${REQ[0]}" ]] || \
       ([[ "${INS[0]}" == "${REQ[0]}" ]] && [[ "${INS[1]:-0}" -lt "${REQ[1]:-0}" ]]); then
        needs_go=true
    fi
fi

if [[ "$needs_go" == "true" ]]; then
    ARCH=$(dpkg --print-architecture)
    case "$ARCH" in
        amd64) GO_ARCH="amd64" ;;
        arm64) GO_ARCH="arm64" ;;
        *) error "Arquitectura no soportada para Go: $ARCH" ;;
    esac
    step "  Descargando Go ${GO_VERSION} (${GO_ARCH})..."
    curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" -o /tmp/go.tar.gz
    rm -rf /usr/local/go
    tar -C /usr/local -xzf /tmp/go.tar.gz
    rm /tmp/go.tar.gz
    # Perfil global
    cat > /etc/profile.d/golang.sh << 'GOEOF'
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
GOEOF
    chmod +x /etc/profile.d/golang.sh
    export PATH=$PATH:/usr/local/go/bin
    info "Go instalado: $(go version)"
else
    export PATH=$PATH:/usr/local/go/bin
    info "Go ya instalado: $(go version)"
fi

# =============================================================================
# 8. QDRANT (binario oficial)
# =============================================================================
step "Instalando Qdrant..."
QDRANT_VERSION="v1.12.1"
QDRANT_INSTALL_DIR="/opt/rss2/qdrant"
mkdir -p "$QDRANT_INSTALL_DIR"

if [[ ! -f "$QDRANT_INSTALL_DIR/qdrant" ]]; then
    ARCH=$(dpkg --print-architecture)
    case "$ARCH" in
        amd64) QDRANT_ARCH="x86_64-unknown-linux-musl" ;;
        arm64) QDRANT_ARCH="aarch64-unknown-linux-musl" ;;
        *) error "Arquitectura no soportada para Qdrant: $ARCH" ;;
    esac
    step "  Descargando Qdrant ${QDRANT_VERSION}..."
    curl -fsSL \
        "https://github.com/qdrant/qdrant/releases/download/${QDRANT_VERSION}/qdrant-${QDRANT_ARCH}.tar.gz" \
        -o /tmp/qdrant.tar.gz
    tar -C "$QDRANT_INSTALL_DIR" -xzf /tmp/qdrant.tar.gz
    chmod +x "$QDRANT_INSTALL_DIR/qdrant"
    rm /tmp/qdrant.tar.gz
    info "Qdrant ${QDRANT_VERSION} instalado en ${QDRANT_INSTALL_DIR}"
else
    info "Qdrant ya instalado en ${QDRANT_INSTALL_DIR}"
fi

# =============================================================================
# 9. USUARIO DEL SISTEMA rss2
# =============================================================================
step "Creando usuario del sistema 'rss2'..."
if ! id rss2 &>/dev/null; then
    useradd -r -m -d /opt/rss2 -s /bin/bash rss2
    info "Usuario 'rss2' creado"
else
    info "Usuario 'rss2' ya existe"
fi

# Crear estructura de directorios
mkdir -p \
    /opt/rss2/bin \
    /opt/rss2/src \
    /opt/rss2/data/wiki_images \
    /opt/rss2/data/qdrant_storage \
    /opt/rss2/hf_cache \
    /opt/rss2/models \
    /opt/rss2/frontend/dist \
    /opt/rss2/logs \
    /opt/rss2/backups
chown -R rss2:rss2 /opt/rss2
info "Directorios /opt/rss2 creados"

# =============================================================================
# 10. PYTHON VIRTUALENV + DEPENDENCIAS BASE
# =============================================================================
step "Creando virtualenv Python en /opt/rss2/venv..."
if [[ ! -d /opt/rss2/venv ]]; then
    python3 -m venv /opt/rss2/venv
fi
/opt/rss2/venv/bin/pip install --upgrade pip setuptools wheel -q
info "Virtualenv listo"

# Dependencias base (sin los modelos pesados de ML)
step "Instalando dependencias Python base..."
/opt/rss2/venv/bin/pip install -q \
    psycopg2-binary \
    langdetect \
    python-dotenv \
    requests \
    beautifulsoup4 \
    lxml \
    redis \
    qdrant-client \
    numpy \
    scikit-learn \
    tqdm
info "Dependencias Python base instaladas"

# =============================================================================
# 11. DEPENDENCIAS ML (pesadas - opcional en este paso)
# =============================================================================
echo ""
echo -e "${YELLOW}[?]${NC} Instalar dependencias ML pesadas ahora?"
echo "    (ctranslate2, transformers, sentence-transformers, spaCy)"
echo "    Puede tardar 20-40 minutos y usar ~5 GB de disco."
echo -n "    [s/N]: "
read -r install_ml

if [[ "${install_ml,,}" == "s" || "${install_ml,,}" == "si" || "${install_ml,,}" == "y" ]]; then
    step "Instalando dependencias ML (esto tarda)..."
    /opt/rss2/venv/bin/pip install -q \
        ctranslate2>=4.0.0 \
        transformers==4.43.3 \
        sentencepiece \
        sacremoses \
        accelerate \
        sentence-transformers==3.0.1 \
        "spacy>=3.7,<4.0" \
        torch --index-url https://download.pytorch.org/whl/cpu
    info "Dependencias ML instaladas"

    step "Descargando modelo spaCy en español..."
    /opt/rss2/venv/bin/python -m spacy download es_core_news_lg
    info "Modelo spaCy es_core_news_lg listo"

    step "Convirtiendo modelo NLLB-200 a CTranslate2..."
    warn "Esto puede tardar 10-30 minutos y requiere ~2 GB de RAM"
    mkdir -p /opt/rss2/models
    /opt/rss2/venv/bin/python - <<'EOF'
import os, sys
os.makedirs("/opt/rss2/models/nllb-ct2", exist_ok=True)
os.environ["HF_HOME"] = "/opt/rss2/hf_cache"
try:
    from ctranslate2.converters import OpusMTConverter
    converter = OpusMTConverter("facebook/nllb-200-distilled-600M")
    converter.convert("/opt/rss2/models/nllb-ct2", quantization="int8", force=True)
    print("[OK] Modelo NLLB-200 convertido en /opt/rss2/models/nllb-ct2")
except Exception as e:
    print(f"[ERROR] {e}")
    print("Convierte manualmente despues con: deploy/debian/convert_model.sh")
    sys.exit(0)
EOF
    chown -R rss2:rss2 /opt/rss2/models /opt/rss2/hf_cache
else
    warn "ML omitido. Ejecuta 'deploy/debian/install.sh' para instalarlas junto con el resto."
    warn "Sin ML: la traduccion y los embeddings no funcionaran."
fi

chown -R rss2:rss2 /opt/rss2

# =============================================================================
# RESUMEN Y SIGUIENTES PASOS
# =============================================================================
echo ""
echo "================================================="
echo -e "  ${GREEN}Prerequisites instalados correctamente${NC}"
echo "================================================="
echo ""
echo "  Sistema:     $PRETTY_NAME"
echo "  Go:          $(go version 2>/dev/null | awk '{print $3}')"
echo "  Python:      $(python3 --version)"
echo "  Node.js:     $(node --version)"
echo "  PostgreSQL:  $(psql --version | awk '{print $3}')"
echo "  Redis:       $(redis-server --version | awk '{print $3}' | tr -d ',')"
echo "  Nginx:       $(nginx -v 2>&1 | cut -d'/' -f2)"
echo ""
echo "  Siguiente paso:"
echo "    sudo bash deploy/debian/install.sh"
echo ""
echo "  Si algo falló durante la instalación:"
echo "    • apt falla:       apt-get update --fix-missing"
echo "    • Go no descarga:  verifica conectividad → curl https://go.dev"
echo "    • Qdrant no baja:  descárgalo manualmente en"
echo "                       https://github.com/qdrant/qdrant/releases"
echo "    • pip falla:       python3 -m venv /opt/rss2/venv --clear"
echo "    • Diagnóstico:     bash deploy/debian/check.sh"
echo ""
