#!/bin/bash

# Script comun para manejo de migraciones de Prisma (Bash)
# Uso: ./scripts/migrate-database.sh [-ForceBaseline] [-VerifyOnly]

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

# Variables
CONTAINER_NAME="ai-learning-platform-ewc-backend"
DB_CONTAINER_NAME="ai-learning-platform-ewc-postgres"

# Funcion para mostrar ayuda
show_help() {
    echo "Uso: ./scripts/migrate-database.sh [-ForceBaseline] [-VerifyOnly] [-Help]"
    echo ""
    echo "Opciones:"
    echo "  -ForceBaseline  Forzar baseline de migraciones"
    echo "  -VerifyOnly     Solo verificar estado de migraciones"
    echo "  -Help           Mostrar esta ayuda"
    exit 0
}

# Funcion para verificar si una migracion realmente se aplico
test_migration_applied() {
    local migration_name="$1"
    local schema_file="$2"
    
    # Verificar si es una migracion de tabla nueva
    if [[ "$migration_name" == *"add_openai_config"* ]]; then
        # Verificar si la tabla openai_config existe
        local table_exists=$(docker exec $DB_CONTAINER_NAME psql -U postgres -d ai_learning_platform -t -c "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'openai_config');" 2>/dev/null | tr -d ' \n\r')
        if [ "$table_exists" = "t" ]; then
            return 0
        else
            return 1
        fi
    fi
    
    # Verificar si es una migracion de columnas en conversations
    if [[ "$migration_name" == *"add_openai_config"* ]]; then
        # Verificar si las columnas de OpenAI existen en conversations
        local columns_exist=$(docker exec $DB_CONTAINER_NAME psql -U postgres -d ai_learning_platform -t -c "SELECT COUNT(*) FROM information_schema.columns WHERE table_name = 'conversations' AND column_name LIKE '%openai%';" 2>/dev/null | tr -d ' \n\r')
        if [ "$columns_exist" -gt 0 ]; then
            return 0
        else
            return 1
        fi
    fi
    
    # Para otras migraciones, asumir que estan bien
    return 0
}

# Funcion para aplicar migraciones con validacion
invoke_migrations() {
    local schema_file="${1:-./prisma/schema.prisma}"
    
    echo -e "${BLUE}[INFO] Aplicando migraciones de base de datos...${NC}"
    
    # Primero intentar aplicar migraciones normalmente
    echo -e "${CYAN}  Intentando aplicar migraciones normalmente...${NC}"
    local migrate_result=$(docker exec $CONTAINER_NAME npx prisma migrate deploy --schema="$schema_file" 2>&1)
    local migrate_exit_code=$?
    
    if [ $migrate_exit_code -eq 0 ]; then
        echo -e "${GREEN}[OK] Migraciones aplicadas exitosamente${NC}"
        echo -e "${GREEN}$migrate_result${NC}"
        
        # Verificar que las migraciones realmente se aplicaron
        echo -e "${CYAN}  Verificando que las migraciones se aplicaron realmente...${NC}"
        test_all_migrations_applied
        return $?
    else
        echo -e "${YELLOW}[WARN] Error al aplicar migraciones, verificando si necesita baseline...${NC}"
        echo -e "${GREEN}$migrate_result${NC}"
        echo ""
        
        # Si es error P3005, la BD tiene tablas pero no tiene baseline de Prisma
        if echo "$migrate_result" | grep -q "P3005\|baseline\|not empty"; then
            echo -e "${BLUE}  Base de datos necesita baseline...${NC}"
            invoke_baseline_migrations "$schema_file"
            return $?
        else
            echo -e "${RED}[ERROR] Error desconocido en migraciones${NC}"
            echo -e "${YELLOW}  Puedes intentar ejecutar manualmente:${NC}"
            echo -e "${GREEN}    docker exec $CONTAINER_NAME npx prisma migrate deploy --schema=$schema_file${NC}"
            return 1
        fi
    fi
}

# Funcion para aplicar baseline de migraciones
invoke_baseline_migrations() {
    local schema_file="$1"
    
    echo -e "${BLUE}  Obteniendo lista de migraciones...${NC}"
    local migration_dirs=$(docker exec $CONTAINER_NAME ls prisma/migrations 2>&1 | grep -E "^\d{14}_" || true)
    
    if [ -z "$migration_dirs" ]; then
        echo -e "${RED}[ERROR] No se encontraron migraciones en el directorio${NC}"
        echo -e "${BLUE}  Verificando directorio de migraciones...${NC}"
        docker exec $CONTAINER_NAME ls -la prisma/migrations 2>&1
        return 1
    fi
    
    local migration_count=$(echo "$migration_dirs" | wc -l)
    echo -e "${CYAN}  Migraciones encontradas: $migration_count${NC}"
    
    # Marcar cada migracion como aplicada SOLO si realmente se aplico
    echo "$migration_dirs" | while read -r migration_dir; do
        local migration_name=$(echo "$migration_dir" | tr -d '\r\n')
        echo -e "${CYAN}  - Verificando migracion: $migration_name${NC}"
        
        # Verificar si la migracion realmente se aplico
        if test_migration_applied "$migration_name" "$schema_file"; then
            echo -e "${GREEN}[OK] $migration_name ya esta aplicada correctamente${NC}"
        else
            echo -e "${YELLOW}[WARN] $migration_name no esta aplicada, marcando como aplicada...${NC}"
            local resolve_result=$(docker exec $CONTAINER_NAME npx prisma migrate resolve --applied "$migration_name" --schema="$schema_file" 2>&1)
            if [ $? -eq 0 ]; then
                echo -e "${GREEN}[OK] $migration_name marcada como aplicada${NC}"
            else
                echo -e "${YELLOW}[WARN] No se pudo marcar $migration_name${NC}"
                echo -e "${GREEN}$resolve_result${NC}"
            fi
        fi
    done
    
    # Ahora intentar aplicar migraciones nuevamente
    echo -e "${BLUE}  Aplicando migraciones despues del baseline...${NC}"
    local final_result=$(docker exec $CONTAINER_NAME npx prisma migrate deploy --schema="$schema_file" 2>&1)
    local final_exit_code=$?
    
    if [ $final_exit_code -eq 0 ]; then
        echo -e "${GREEN}[OK] Todas las migraciones aplicadas exitosamente${NC}"
        echo -e "${GREEN}$final_result${NC}"
        
        # Verificar que las migraciones realmente se aplicaron
        test_all_migrations_applied
        return $?
    else
        echo -e "${YELLOW}[WARN] Algunas migraciones pueden estar pendientes${NC}"
        echo -e "${GREEN}$final_result${NC}"
        return 1
    fi
}

# Funcion para verificar que todas las migraciones se aplicaron realmente
test_all_migrations_applied() {
    echo -e "${CYAN}  Verificando que todas las migraciones se aplicaron realmente...${NC}"
    
    # Verificar migraciones especificas conocidas
    local all_good=true
    
    # Verificar migracion de OpenAI
    if ! test_migration_applied "add_openai_config" ""; then
        echo -e "${RED}[ERROR] Migracion de OpenAI no se aplico correctamente${NC}"
        all_good=false
    else
        echo -e "${GREEN}[OK] Migracion de OpenAI aplicada correctamente${NC}"
    fi
    
    # Puedes agregar mas verificaciones especificas aqui
    
    if [ "$all_good" = true ]; then
        echo -e "${GREEN}[OK] Todas las migraciones verificadas correctamente${NC}"
        return 0
    else
        echo -e "${RED}[ERROR] Algunas migraciones no se aplicaron correctamente${NC}"
        return 1
    fi
}

# Funcion para verificar solo el estado de las migraciones
test_migration_status() {
    echo -e "${BLUE}[INFO] Verificando estado de migraciones...${NC}"
    
    local status_result=$(docker exec $CONTAINER_NAME npx prisma migrate status --schema="./prisma/schema.prisma" 2>&1)
    local status_exit_code=$?
    
    if [ $status_exit_code -eq 0 ]; then
        echo -e "${GREEN}[OK] Estado de migraciones:${NC}"
        echo -e "${GREEN}$status_result${NC}"
        
        # Verificar que las migraciones realmente se aplicaron
        test_all_migrations_applied
        return $?
    else
        echo -e "${RED}[ERROR] Error al verificar estado de migraciones:${NC}"
        echo -e "${GREEN}$status_result${NC}"
        return 1
    fi
}

# Funcion principal
main() {
    echo -e "${BLUE}[INFO] Iniciando proceso de migraciones de base de datos...${NC}"
    echo ""
    
    # Verificar que los contenedores esten ejecutandose
    echo -e "${CYAN}[DEBUG] Verificando contenedores...${NC}"
    local all_containers=$(docker ps)
    echo -e "${CYAN}[DEBUG] Contenedores encontrados:${NC}"
    echo -e "${GREEN}$all_containers${NC}"
    
    local backend_running=$(docker ps | grep "$CONTAINER_NAME")
    echo -e "${CYAN}[DEBUG] Backend running: $([ -n "$backend_running" ] && echo "true" || echo "false")${NC}"
    if [ -z "$backend_running" ]; then
        echo -e "${RED}[ERROR] Contenedor $CONTAINER_NAME no esta ejecutandose${NC}"
        exit 1
    fi
    
    local db_running=$(docker ps | grep "$DB_CONTAINER_NAME")
    echo -e "${CYAN}[DEBUG] DB running: $([ -n "$db_running" ] && echo "true" || echo "false")${NC}"
    if [ -z "$db_running" ]; then
        echo -e "${RED}[ERROR] Contenedor $DB_CONTAINER_NAME no esta ejecutandose${NC}"
        exit 1
    fi
    
    # Verificar que la base de datos existe
    local db_exists=$(docker exec $DB_CONTAINER_NAME psql -U postgres -lqt | grep "ai_learning_platform")
    if [ -z "$db_exists" ]; then
        echo -e "${YELLOW}[WARN] La base de datos no existe${NC}"
        echo -e "${BLUE}[INFO] Creando base de datos...${NC}"
        docker exec $DB_CONTAINER_NAME psql -U postgres -c "CREATE DATABASE ai_learning_platform;"
        if [ $? -eq 0 ]; then
            echo -e "${GREEN}[OK] Base de datos creada exitosamente${NC}"
        else
            echo -e "${RED}[ERROR] Error al crear base de datos${NC}"
            exit 1
        fi
    fi
    
    # Ejecutar segun el modo
    local success=false
    if [ "$VERIFY_ONLY" = true ]; then
        test_migration_status
        success=$?
    else
        invoke_migrations
        success=$?
    fi
    
    if [ $success -eq 0 ]; then
        echo ""
        echo -e "${GREEN}[OK] Proceso de migraciones completado exitosamente${NC}"
        exit 0
    else
        echo ""
        echo -e "${RED}[ERROR] Proceso de migraciones fallo${NC}"
        exit 1
    fi
}

# Procesar argumentos
FORCE_BASELINE=false
VERIFY_ONLY=false

while [[ $# -gt 0 ]]; do
    case $1 in
        -ForceBaseline|--force-baseline)
            FORCE_BASELINE=true
            shift
            ;;
        -VerifyOnly|--verify-only)
            VERIFY_ONLY=true
            shift
            ;;
        -Help|--help|-h)
            show_help
            ;;
        *)
            echo -e "${RED}Error: Argumento desconocido $1${NC}"
            show_help
            ;;
    esac
done

# Ejecutar funcion principal
main

