#!/bin/bash

# AI Learning Platform Health Check Script
# Verifica el estado de todos los componentes de la plataforma de aprendizaje AI
# Incluye verificación de contenedores Docker, servicios, base de datos y conectividad

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

# Configuración
FRONTEND_URL="https://chat.englishworldcenter.com"
GRPC_HOST="localhost"
GRPC_PORT="7233"
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="ai_learning_platform"
WORKER_CHECK_URL="https://chat.englishworldcenter.com/health"

# Nombres de contenedores (debe coincidir con docker-compose.yml)
POSTGRES_CONTAINER="ai-learning-platform-ewc-postgres"
TEMPORAL_CONTAINER="ai-learning-platform-ewc-temporal"
BACKEND_CONTAINER="ai-learning-platform-ewc-backend"
FRONTEND_DEV_CONTAINER="ai-learning-platform-ewc-frontend-dev"
FRONTEND_PROD_CONTAINER="ai-learning-platform-ewc-frontend-prod"

# Red Docker (docker-compose.yml -> networks.english-network.name)
DOCKER_NETWORK="english-network"

# Función para logging
log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

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

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

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

# Función para verificar HTTP status
check_http() {
    local url=$1
    local name=$2
    local expected_status=${3:-200}
    
    log "Verificando $name: $url"
    
    response=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 30 "$url")
    
    if [ "$response" -eq "$expected_status" ]; then
        log_success "$name está funcionando (HTTP $response)"
        return 0
    else
        log_error "$name falló (HTTP $response, esperado $expected_status)"
        return 1
    fi
}

# Función para verificar gRPC
check_grpc() {
    local host=$1
    local port=$2
    local name=$3
    
    log "Verificando $name: $host:$port"
    
    # Usar nc para verificar si el puerto está abierto
    if nc -z -w5 "$host" "$port" 2>/dev/null; then
        log_success "$name está funcionando (puerto $port abierto)"
        return 0
    else
        log_error "$name falló (puerto $port cerrado o inaccesible)"
        return 1
    fi
}

# Función para verificar base de datos
check_database() {
    local host=$1
    local port=$2
    local dbname=$3
    local name=$4
    
    log "Verificando $name: $host:$port/$dbname"
    
    # Verificar si el puerto está abierto
    if ! nc -z -w5 "$host" "$port" 2>/dev/null; then
        log_error "$name falló (puerto $port cerrado)"
        return 1
    fi
}

# Función para verificar workers
check_workers() {
    local url=$1
    local name=$2
    
    log "Verificando $name: $url"
    
    response=$(curl -s --connect-timeout 10 --max-time 30 "$url")
    
    if [ $? -eq 0 ] && echo "$response" | grep -q "healthy\|ok\|running"; then
        log_success "$name está funcionando"
        return 0
    else
        log_error "$name falló o no responde correctamente"
        return 1
    fi
}

# Función para verificar WebSocket
check_websocket() {
    local url=$1
    local name=$2
    
    log "Verificando $name: $url"
    
    # Usar wscat si está disponible, sino usar curl
    if command -v wscat >/dev/null 2>&1; then
        # Usar gtimeout si está disponible (macOS), sino timeout
        if command -v gtimeout >/dev/null 2>&1; then
            gtimeout 5 wscat -c "$url" --no-color >/dev/null 2>&1
        else
            timeout 5 wscat -c "$url" --no-color >/dev/null 2>&1
        fi
        
        # gtimeout devuelve 124 cuando se agota el tiempo pero la conexión fue exitosa
        local exit_code=$?
        if [ $exit_code -eq 0 ] || [ $exit_code -eq 124 ]; then
            log_success "$name está funcionando"
            return 0
        else
            log_error "$name falló (WebSocket no responde)"
            return 1
        fi
    else
        log_warning "$name: wscat no disponible, saltando verificación WebSocket"
        return 0
    fi
}

# Función para verificar contenedores Docker
check_docker_containers() {
    log "Verificando contenedores Docker..."
    
    local errors=0
    local warnings=0
    
    # Verificar PostgreSQL
    if docker ps --format "table {{.Names}}" | grep -q "^${POSTGRES_CONTAINER}$"; then
        local status=$(docker inspect --format='{{.State.Status}}' "$POSTGRES_CONTAINER" 2>/dev/null)
        if [ "$status" = "running" ]; then
            log_success "Contenedor PostgreSQL está ejecutándose"
        else
            log_error "Contenedor PostgreSQL no está ejecutándose (estado: $status)"
            ((errors++))
        fi
    else
        log_error "Contenedor PostgreSQL no encontrado"
        ((errors++))
    fi
    
    # Verificar Temporal
    if docker ps --format "table {{.Names}}" | grep -q "^${TEMPORAL_CONTAINER}$"; then
        local status=$(docker inspect --format='{{.State.Status}}' "$TEMPORAL_CONTAINER" 2>/dev/null)
        if [ "$status" = "running" ]; then
            log_success "Contenedor Temporal está ejecutándose"
        else
            log_error "Contenedor Temporal no está ejecutándose (estado: $status)"
            ((errors++))
        fi
    else
        log_error "Contenedor Temporal no encontrado"
        ((errors++))
    fi
    
    # Verificar Backend
    if docker ps --format "table {{.Names}}" | grep -q "^${BACKEND_CONTAINER}$"; then
        local status=$(docker inspect --format='{{.State.Status}}' "$BACKEND_CONTAINER" 2>/dev/null)
        if [ "$status" = "running" ]; then
            log_success "Contenedor Backend está ejecutándose"
        else
            log_error "Contenedor Backend no está ejecutándose (estado: $status)"
            ((errors++))
        fi
    else
        log_error "Contenedor Backend no encontrado"
        ((errors++))
    fi
    
    # Verificar Frontend (dev o prod)
    local frontend_running=false
    if docker ps --format "table {{.Names}}" | grep -q "^${FRONTEND_DEV_CONTAINER}$"; then
        local status=$(docker inspect --format='{{.State.Status}}' "$FRONTEND_DEV_CONTAINER" 2>/dev/null)
        if [ "$status" = "running" ]; then
            log_success "Contenedor Frontend (dev) está ejecutándose"
            frontend_running=true
        else
            log_warning "Contenedor Frontend (dev) no está ejecutándose (estado: $status)"
        fi
    fi
    
    if docker ps --format "table {{.Names}}" | grep -q "^${FRONTEND_PROD_CONTAINER}$"; then
        local status=$(docker inspect --format='{{.State.Status}}' "$FRONTEND_PROD_CONTAINER" 2>/dev/null)
        if [ "$status" = "running" ]; then
            log_success "Contenedor Frontend (prod) está ejecutándose"
            frontend_running=true
        else
            log_warning "Contenedor Frontend (prod) no está ejecutándose (estado: $status)"
        fi
    fi
    
    if [ "$frontend_running" = false ]; then
        log_error "Ningún contenedor Frontend está ejecutándose"
        ((errors++))
    fi
    
    # Verificar red Docker
    if docker network ls --format "table {{.Name}}" | grep -q "^${DOCKER_NETWORK}$"; then
        log_success "Red Docker '${DOCKER_NETWORK}' existe"
    else
        log_warning "Red Docker '${DOCKER_NETWORK}' no encontrada"
        ((warnings++))
    fi
    
    return $errors
}

# Función para verificar volúmenes Docker
check_docker_volumes() {
    log "Verificando volúmenes Docker..."
    
    local errors=0
    local warnings=0
    
    # Verificar volumen de PostgreSQL
    if docker volume ls --format "table {{.Name}}" | grep -q "^ai-learning-platform-postgres-data$"; then
        log_success "Volumen PostgreSQL existe"
    else
        log_error "Volumen PostgreSQL no encontrado"
        ((errors++))
    fi
    
    # Verificar volumen de uploads del backend
    if docker volume ls --format "table {{.Name}}" | grep -q "^ai-learning-platform-backend-uploads$"; then
        log_success "Volumen Backend Uploads existe"
    else
        log_warning "Volumen Backend Uploads no encontrado"
        ((warnings++))
    fi
    
    # Verificar volumen de logs del backend
    if docker volume ls --format "table {{.Name}}" | grep -q "^ai-learning-platform-backend-logs$"; then
        log_success "Volumen Backend Logs existe"
    else
        log_warning "Volumen Backend Logs no encontrado"
        ((warnings++))
    fi
    
    return $errors
}

# Función principal
main() {
    echo "=========================================="
    echo "🔍 AI LEARNING PLATFORM HEALTH CHECK"
    echo "=========================================="
    echo
    
    local errors=0
    local warnings=0
    
    # 1. Verificar Contenedores Docker
    echo "🐳 DOCKER CONTAINERS CHECK"
    echo "---------------------------"
    if ! check_docker_containers; then
        ((errors++))
    fi
    echo
    
    # 2. Verificar Volúmenes Docker
    echo "💾 DOCKER VOLUMES CHECK"
    echo "------------------------"
    if ! check_docker_volumes; then
        ((warnings++))
    fi
    echo
    
    # 3. Verificar Frontend
    echo "📱 FRONTEND CHECK"
    echo "-----------------"
    if ! check_http "$FRONTEND_URL" "Frontend"; then
        ((errors++))
    fi
    echo
    
    # 4. Verificar gRPC
    echo "🔌 GRPC CHECK"
    echo "-------------"
    if ! check_grpc "$GRPC_HOST" "$GRPC_PORT" "Temporal gRPC"; then
        ((errors++))
    fi
    echo
    
    # 5. Verificar Base de Datos
    echo "🗄️  DATABASE CHECK"
    echo "------------------"
    if ! check_database "$DB_HOST" "$DB_PORT" "$DB_NAME" "PostgreSQL"; then
        ((errors++))
    fi
    echo
    
    # 6. Verificar Workers
    echo "⚙️  WORKERS CHECK"
    echo "-----------------"
    if ! check_workers "$WORKER_CHECK_URL" "Temporal Workers"; then
        ((warnings++))
    fi
    echo
    
    # 7. Verificar WebSocket
    echo "🌐 WEBSOCKET CHECK"
    echo "-------------------"
    if ! check_websocket "ws://localhost:3000/ws" "WebSocket"; then
        ((warnings++))
    fi
    echo
    
    # 8. Verificar CSP y recursos externos
    echo "🔒 SECURITY CHECK"
    echo "------------------"
    log "Verificando Content Security Policy..."
    
    # Verificar si Font Awesome está bloqueado
    font_awesome_response=$(curl -s -o /dev/null -w "%{http_code}" "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css")
    if [ "$font_awesome_response" -ne 200 ]; then
        log_warning "Font Awesome puede estar bloqueado por CSP (HTTP $font_awesome_response)"
        ((warnings++))
    else
        log_success "Font Awesome accesible"
    fi
    
    # Verificar Google Fonts
    google_fonts_response=$(curl -s -o /dev/null -w "%{http_code}" "https://fonts.googleapis.com/css?family=Outfit:wght@400;700&display=swap")
    if [ "$google_fonts_response" -ne 200 ]; then
        log_warning "Google Fonts puede estar bloqueado por CSP (HTTP $google_fonts_response)"
        ((warnings++))
    else
        log_success "Google Fonts accesible"
    fi
    echo
    
    # Resumen final
    echo "=========================================="
    echo "📊 RESUMEN DE HEALTH CHECK"
    echo "=========================================="
    
    if [ $errors -eq 0 ] && [ $warnings -eq 0 ]; then
        log_success "✅ Todos los servicios están funcionando correctamente"
        exit 0
    elif [ $errors -eq 0 ]; then
        log_warning "⚠️  Hay $warnings advertencias, pero no hay errores críticos"
        exit 0
    else
        log_error "❌ Se encontraron $errors errores críticos y $warnings advertencias"
        echo
        echo "🔧 ACCIONES RECOMENDADAS:"
        echo "1. Verificar estado de contenedores: docker ps"
        echo "2. Iniciar servicios: docker compose up -d"
        echo "3. Verificar logs: docker compose logs [servicio]"
        echo "4. Reiniciar contenedores: docker compose restart"
        echo "5. Verificar configuración de CSP en el servidor web"
        echo "6. Revisar configuración de WebSocket y autenticación"
        echo "7. Revisar logs del servidor para más detalles"
        echo
        echo "📋 COMANDOS ÚTILES:"
        echo "• Ver todos los contenedores: docker ps -a"
        echo "• Ver logs de un contenedor: docker logs $BACKEND_CONTAINER"
        echo "• Reiniciar un contenedor: docker restart $BACKEND_CONTAINER"
        echo "• Ver estado de la red: docker network ls"
        echo "• Verificar volúmenes: docker volume ls"
        echo "• Verificar recursos: docker stats"
        echo "• Verificar estado de la base de datos: docker exec $POSTGRES_CONTAINER pg_isready -U postgres"
        echo "• Verificar estado de los workers: docker exec $TEMPORAL_CONTAINER temporal workflow list"
        echo "• Verificar estado de la WebSocket: docker exec $BACKEND_CONTAINER curl -s http://localhost:3000/ws"
        echo "• Verificar estado de la API: docker exec $BACKEND_CONTAINER curl -s http://localhost:3000/health"
        echo "• Verificar estado de la base de datos: docker exec $POSTGRES_CONTAINER pg_isready -U postgres"
        echo "• Verificar estado de los workers: docker exec $TEMPORAL_CONTAINER temporal workflow list"
        echo "• Verificar estado de la WebSocket: docker exec $BACKEND_CONTAINER curl -s http://localhost:3000/ws"
        exit 1
    fi
}

# Ejecutar script
main "$@"
