#!/bin/bash

#############################################################
#  DEPLOY SCRIPT PARA VPS - WhatsApp Bot
#  
#  Uso: ./deploy-vps.sh [opciones]
#  
#  Opciones:
#    --install    Primera instalación (instala Docker, etc)
#    --update     Solo actualizar código y reiniciar
#    --ssl        Generar/renovar certificados SSL
#    --logs       Ver logs de la aplicación
#    --status     Ver estado de los contenedores
#############################################################

set -e

# ==================== CONFIGURACIÓN ====================
# Modificar estos valores según tu VPS

DOMAIN="bot.u-s.app"           # Tu dominio
EMAIL="admin@u-s.app"          # Email para Let's Encrypt
APP_DIR="/var/www/whatsapp"    # Directorio de la app en VPS
COMPOSE_FILE="docker-compose.prod.yml"

# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ==================== FUNCIONES ====================

log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[OK]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Verificar que se ejecuta como root o con sudo
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "Este script debe ejecutarse como root o con sudo"
        exit 1
    fi
}

# Instalar Docker y Docker Compose
install_docker() {
    log_info "Instalando Docker..."
    
    # Verificar si Docker ya está instalado
    if command -v docker &> /dev/null; then
        log_success "Docker ya está instalado: $(docker --version)"
    else
        curl -fsSL https://get.docker.com | sh
        systemctl enable docker
        systemctl start docker
        log_success "Docker instalado correctamente"
    fi
    
    # Verificar Docker Compose
    if command -v docker-compose &> /dev/null || docker compose version &> /dev/null; then
        log_success "Docker Compose disponible"
    else
        log_info "Instalando Docker Compose plugin..."
        apt-get update
        apt-get install -y docker-compose-plugin
        log_success "Docker Compose instalado"
    fi
}

# Instalar Certbot para SSL
install_certbot() {
    log_info "Instalando Certbot para SSL..."
    
    if command -v certbot &> /dev/null; then
        log_success "Certbot ya está instalado"
    else
        apt-get update
        apt-get install -y certbot
        log_success "Certbot instalado"
    fi
}

# Generar certificados SSL con Let's Encrypt
generate_ssl() {
    log_info "Generando certificados SSL para ${DOMAIN}..."
    
    # Detener contenedores que usan puerto 80
    cd "$APP_DIR"
    docker compose -f "$COMPOSE_FILE" down 2>/dev/null || true
    
    # Generar certificado
    certbot certonly \
        --standalone \
        --preferred-challenges http \
        --agree-tos \
        --email "$EMAIL" \
        -d "$DOMAIN" \
        --non-interactive
    
    if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then
        log_success "Certificado SSL generado correctamente"
        
        # Crear directorio y copiar certificados
        mkdir -p "$APP_DIR/docker/ssl"
        cp "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" "$APP_DIR/docker/ssl/server.crt"
        cp "/etc/letsencrypt/live/${DOMAIN}/privkey.pem" "$APP_DIR/docker/ssl/server.key"
        chmod 600 "$APP_DIR/docker/ssl/server.key"
        
        log_success "Certificados copiados a docker/ssl/"
    else
        log_error "Error generando certificado SSL"
        exit 1
    fi
}

# Renovar certificados SSL
renew_ssl() {
    log_info "Renovando certificados SSL..."
    
    cd "$APP_DIR"
    docker compose -f "$COMPOSE_FILE" stop app 2>/dev/null || true
    
    certbot renew --standalone
    
    # Copiar certificados actualizados
    if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then
        cp "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" "$APP_DIR/docker/ssl/server.crt"
        cp "/etc/letsencrypt/live/${DOMAIN}/privkey.pem" "$APP_DIR/docker/ssl/server.key"
        log_success "Certificados renovados"
    fi
    
    docker compose -f "$COMPOSE_FILE" start app
}

# Configurar cron para renovación automática de SSL
setup_ssl_cron() {
    log_info "Configurando renovación automática de SSL..."
    
    CRON_CMD="0 3 * * * cd $APP_DIR && docker compose -f $COMPOSE_FILE stop app && certbot renew --quiet && docker compose -f $COMPOSE_FILE start app"
    
    # Añadir al crontab si no existe
    (crontab -l 2>/dev/null | grep -v "certbot renew"; echo "$CRON_CMD") | crontab -
    
    log_success "Cron configurado para renovar SSL cada día a las 3am"
}

# Crear archivo .env si no existe
create_env_file() {
    if [ ! -f "$APP_DIR/.env" ]; then
        log_info "Creando archivo .env..."
        
        cat > "$APP_DIR/.env" << 'EOF'
# ============================================
# CONFIGURACIÓN DE PRODUCCIÓN
# ============================================

# Base de datos
DB_HOST=77.37.126.126
DB_PORT=3306
DB_NAME=usite_whatsapp_bot
DB_USER=usite_whatsapp_user
DB_PASS=6q!Vio0fn@PFmsLyHjH5

# Redis (opcional, dejar vacío si no usa password)
REDIS_PASSWORD=

# WhatsApp API (obtener de Facebook Developer)
WHATSAPP_TOKEN=
WHATSAPP_PHONE_NUMBER_ID=
WEBHOOK_VERIFY_TOKEN=
EOF
        
        log_warn "Archivo .env creado. ¡EDITA LAS CREDENCIALES antes de continuar!"
        log_warn "Ejecuta: nano $APP_DIR/.env"
    else
        log_success "Archivo .env ya existe"
    fi
}

# Crear directorios necesarios
create_directories() {
    log_info "Creando directorios..."
    
    mkdir -p "$APP_DIR/logs"
    mkdir -p "$APP_DIR/uploads"
    mkdir -p "$APP_DIR/docker/ssl"
    
    # Permisos
    chown -R www-data:www-data "$APP_DIR/logs" 2>/dev/null || true
    chown -R www-data:www-data "$APP_DIR/uploads" 2>/dev/null || true
    chmod -R 755 "$APP_DIR/logs"
    chmod -R 755 "$APP_DIR/uploads"
    
    log_success "Directorios creados"
}

# Construir y levantar contenedores
deploy() {
    log_info "Desplegando aplicación..."
    
    cd "$APP_DIR"
    
    # Construir imágenes
    log_info "Construyendo imágenes Docker..."
    docker compose -f "$COMPOSE_FILE" build --no-cache
    
    # Detener contenedores existentes (NO borra volúmenes, los datos persisten)
    log_info "Deteniendo contenedores anteriores..."
    docker compose -f "$COMPOSE_FILE" down --remove-orphans 2>/dev/null || true
    
    # Levantar nuevos contenedores
    log_info "Levantando contenedores..."
    docker compose -f "$COMPOSE_FILE" up -d
    
    # Esperar a que estén listos
    log_info "Esperando a que los servicios estén listos..."
    sleep 10
    
    # Verificar estado
    if docker compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then
        log_success "Contenedores ejecutándose correctamente"
    else
        log_error "Error iniciando contenedores"
        docker compose -f "$COMPOSE_FILE" logs --tail=50
        exit 1
    fi
}

# Actualizar código y reiniciar
update() {
    log_info "Actualizando aplicación..."
    
    cd "$APP_DIR"
    
    # Si es un repo git, hacer pull
    if [ -d ".git" ]; then
        log_info "Actualizando desde Git..."
        git pull origin main || git pull origin master
    fi
    
    # Reconstruir y reiniciar
    docker compose -f "$COMPOSE_FILE" build
    docker compose -f "$COMPOSE_FILE" up -d
    
    log_success "Aplicación actualizada"
}

# Ver logs
show_logs() {
    cd "$APP_DIR"
    docker compose -f "$COMPOSE_FILE" logs -f --tail=100
}

# Ver estado
show_status() {
    cd "$APP_DIR"
    
    echo ""
    echo "==================== ESTADO DE CONTENEDORES ===================="
    docker compose -f "$COMPOSE_FILE" ps
    
    echo ""
    echo "==================== USO DE RECURSOS ===================="
    docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
    
    echo ""
    echo "==================== VERIFICACIÓN DE SERVICIOS ===================="
    
    # Verificar HTTP
    HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost/health.php" 2>/dev/null || echo "ERROR")
    if [ "$HTTP_STATUS" = "200" ]; then
        log_success "HTTP: OK (status $HTTP_STATUS)"
    else
        log_error "HTTP: FALLO (status $HTTP_STATUS)"
    fi
    
    # Verificar HTTPS
    HTTPS_STATUS=$(curl -sk -o /dev/null -w "%{http_code}" "https://localhost/health.php" 2>/dev/null || echo "ERROR")
    if [ "$HTTPS_STATUS" = "200" ]; then
        log_success "HTTPS: OK (status $HTTPS_STATUS)"
    else
        log_warn "HTTPS: $HTTPS_STATUS (puede necesitar certificados SSL)"
    fi
    
    echo ""
    echo "==================== URLS ===================="
    echo "  App:    https://${DOMAIN}"
    echo "  Health: https://${DOMAIN}/health.php"
}

# Primera instalación completa
full_install() {
    check_root
    
    echo ""
    echo "=========================================="
    echo "  INSTALACIÓN COMPLETA - WhatsApp Bot"
    echo "=========================================="
    echo ""
    
    install_docker
    install_certbot
    create_directories
    create_env_file
    
    echo ""
    log_warn "ANTES DE CONTINUAR:"
    log_warn "1. Edita el archivo .env con tus credenciales"
    log_warn "2. Asegúrate que el dominio ${DOMAIN} apunta a este servidor"
    echo ""
    read -p "¿Continuar con el deploy? (s/n): " -n 1 -r
    echo ""
    
    if [[ $REPLY =~ ^[Ss]$ ]]; then
        generate_ssl
        setup_ssl_cron
        deploy
        show_status
    else
        log_info "Deploy cancelado. Ejecuta './deploy-vps.sh' cuando estés listo."
    fi
}

# Mostrar ayuda
show_help() {
    echo ""
    echo "Uso: ./deploy-vps.sh [opción]"
    echo ""
    echo "Opciones:"
    echo "  --install    Primera instalación completa"
    echo "  --update     Actualizar código y reiniciar"
    echo "  --ssl        Generar/renovar certificados SSL"
    echo "  --logs       Ver logs en tiempo real"
    echo "  --status     Ver estado de servicios"
    echo "  --help       Mostrar esta ayuda"
    echo ""
    echo "Ejemplos:"
    echo "  sudo ./deploy-vps.sh --install   # Primera vez"
    echo "  sudo ./deploy-vps.sh --update    # Actualizar"
    echo "  ./deploy-vps.sh --logs           # Ver logs"
    echo ""
}

# ==================== MAIN ====================

case "${1:-}" in
    --install)
        full_install
        ;;
    --update)
        update
        ;;
    --ssl)
        check_root
        generate_ssl
        ;;
    --renew-ssl)
        check_root
        renew_ssl
        ;;
    --logs)
        show_logs
        ;;
    --status)
        show_status
        ;;
    --help|-h)
        show_help
        ;;
    *)
        # Sin argumentos, hacer deploy normal
        if [ ! -d "$APP_DIR" ] || [ ! -f "$APP_DIR/$COMPOSE_FILE" ]; then
            log_error "Directorio de aplicación no encontrado: $APP_DIR"
            log_info "Para primera instalación usa: sudo ./deploy-vps.sh --install"
            exit 1
        fi
        deploy
        show_status
        ;;
esac
