#!/bin/bash
# ============================================================================
# CREATE DATABASE SCRIPT - OrbiQuant IA
# ============================================================================
#
# Script de carga limpia para crear la base de datos desde DDL.
# Cumple con DIRECTIVA-POLITICA-CARGA-LIMPIA.md
#
# USO:
#   ./create-database.sh                    # Crear BD (si no existe)
#   ./create-database.sh --drop-first       # Drop y recrear
#   ./create-database.sh --seeds-only       # Solo ejecutar seeds
#
# ============================================================================

set -e

# 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
DB_NAME="${DB_NAME:-orbiquant}"
DB_USER="${DB_USER:-orbiquant_user}"
DB_PASSWORD="${DB_PASSWORD:-orbiquant_dev_2025}"
DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DDL_DIR="$SCRIPT_DIR/../ddl"
SEEDS_DIR="$SCRIPT_DIR/../seeds"

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

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

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

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

# Función para ejecutar SQL
run_sql() {
    local file=$1
    local description=$2

    if [ -f "$file" ]; then
        log "Ejecutando: $description"
        PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -f "$file" -q
        log_success "$description"
    else
        log_warning "Archivo no encontrado: $file"
    fi
}

# Función para ejecutar SQL en orden
run_sql_dir() {
    local dir=$1
    local description=$2

    if [ -d "$dir" ]; then
        log "Procesando directorio: $description"
        for file in "$dir"/*.sql; do
            if [ -f "$file" ]; then
                local filename=$(basename "$file")
                run_sql "$file" "$filename"
            fi
        done
    else
        log_warning "Directorio no encontrado: $dir"
    fi
}

# Verificar conexión
check_connection() {
    log "Verificando conexión a PostgreSQL..."
    if PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d postgres -c '\q' 2>/dev/null; then
        log_success "Conexión exitosa"
    else
        log_error "No se puede conectar a PostgreSQL"
        exit 1
    fi
}

# Drop database si existe
drop_database() {
    log "Eliminando base de datos $DB_NAME si existe..."
    PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d postgres -c "DROP DATABASE IF EXISTS $DB_NAME;" -q
    log_success "Base de datos eliminada"
}

# Crear database
create_database() {
    log "Creando base de datos $DB_NAME..."
    PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d postgres -c "CREATE DATABASE $DB_NAME WITH ENCODING 'UTF8' LC_COLLATE='en_US.UTF-8' LC_CTYPE='en_US.UTF-8' TEMPLATE=template0;" -q 2>/dev/null || true
    log_success "Base de datos creada"
}

# Crear schemas
create_schemas() {
    log "Creando schemas..."
    PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -q << EOF
-- Schemas principales
CREATE SCHEMA IF NOT EXISTS auth;
CREATE SCHEMA IF NOT EXISTS education;
CREATE SCHEMA IF NOT EXISTS trading;
CREATE SCHEMA IF NOT EXISTS investment;
CREATE SCHEMA IF NOT EXISTS financial;
CREATE SCHEMA IF NOT EXISTS ml;
CREATE SCHEMA IF NOT EXISTS llm;
CREATE SCHEMA IF NOT EXISTS audit;

-- Comentarios
COMMENT ON SCHEMA auth IS 'Autenticación y usuarios';
COMMENT ON SCHEMA education IS 'Plataforma educativa';
COMMENT ON SCHEMA trading IS 'Trading y paper engine';
COMMENT ON SCHEMA investment IS 'Cuentas PAMM';
COMMENT ON SCHEMA financial IS 'Pagos, suscripciones, wallets';
COMMENT ON SCHEMA ml IS 'Machine Learning signals';
COMMENT ON SCHEMA llm IS 'LLM Agent';
COMMENT ON SCHEMA audit IS 'Auditoría y logs';

-- Search path
ALTER DATABASE $DB_NAME SET search_path TO auth, public;
EOF
    log_success "Schemas creados"
}

# Cargar extensiones
load_extensions() {
    log "Cargando extensiones..."
    PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -q << EOF
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "btree_gin";
-- CREATE EXTENSION IF NOT EXISTS "vector";  -- Descomentar cuando se instale pgvector
EOF
    log_success "Extensiones cargadas"
}

# Cargar DDL por schema
load_ddl() {
    local schema=$1
    local schema_dir="$DDL_DIR/schemas/$schema"

    log "Cargando DDL para schema: $schema"

    # 1. Enums primero
    if [ -f "$schema_dir/00-enums.sql" ]; then
        run_sql "$schema_dir/00-enums.sql" "$schema: ENUMs"
    fi

    # 2. Tablas en orden
    run_sql_dir "$schema_dir/tables" "$schema: Tables"

    # 3. Funciones
    run_sql_dir "$schema_dir/functions" "$schema: Functions"

    # 4. Triggers
    run_sql_dir "$schema_dir/triggers" "$schema: Triggers"

    # 5. Views
    run_sql_dir "$schema_dir/views" "$schema: Views"

    # 6. Indexes adicionales
    if [ -f "$schema_dir/99-indexes.sql" ]; then
        run_sql "$schema_dir/99-indexes.sql" "$schema: Indexes"
    fi

    log_success "Schema $schema cargado"
}

# Cargar todos los DDL
load_all_ddl() {
    log "Cargando todos los DDL..."

    # Orden de carga (respeta dependencias)
    local schemas=("auth" "education" "financial" "trading" "investment" "ml" "llm" "audit")

    for schema in "${schemas[@]}"; do
        if [ -d "$DDL_DIR/schemas/$schema" ]; then
            load_ddl "$schema"
        else
            log_warning "Schema $schema no tiene DDL definido"
        fi
    done

    log_success "Todos los DDL cargados"
}

# Cargar seeds
load_seeds() {
    local env=${1:-prod}
    local seeds_path="$SEEDS_DIR/$env"

    log "Cargando seeds ($env)..."

    if [ -d "$seeds_path" ]; then
        for schema_dir in "$seeds_path"/*/; do
            if [ -d "$schema_dir" ]; then
                local schema=$(basename "$schema_dir")
                run_sql_dir "$schema_dir" "Seeds: $schema"
            fi
        done
        log_success "Seeds cargados"
    else
        log_warning "No hay seeds para ambiente: $env"
    fi
}

# Validar integridad
validate_database() {
    log "Validando integridad de la base de datos..."

    # Contar tablas por schema
    local result=$(PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -t -c "
        SELECT schemaname, COUNT(*)
        FROM pg_tables
        WHERE schemaname IN ('auth', 'education', 'trading', 'investment', 'financial', 'ml', 'llm', 'audit')
        GROUP BY schemaname
        ORDER BY schemaname;
    ")

    echo ""
    echo "=== Resumen de Tablas por Schema ==="
    echo "$result"
    echo ""

    # Verificar FKs
    local fk_count=$(PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -t -c "
        SELECT COUNT(*) FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY';
    ")
    log_success "Foreign Keys: $fk_count"

    log_success "Validación completada"
}

# Main
main() {
    echo ""
    echo "=============================================="
    echo "  OrbiQuant IA - Database Setup"
    echo "  Política de Carga Limpia (DDL-First)"
    echo "=============================================="
    echo ""

    local drop_first=false
    local seeds_only=false
    local seed_env="prod"

    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --drop-first)
                drop_first=true
                shift
                ;;
            --seeds-only)
                seeds_only=true
                shift
                ;;
            --env)
                seed_env=$2
                shift 2
                ;;
            *)
                log_error "Argumento desconocido: $1"
                exit 1
                ;;
        esac
    done

    check_connection

    if [ "$seeds_only" = true ]; then
        load_seeds "$seed_env"
        exit 0
    fi

    if [ "$drop_first" = true ]; then
        drop_database
    fi

    create_database
    create_schemas
    load_extensions
    load_all_ddl
    load_seeds "$seed_env"
    validate_database

    echo ""
    log_success "Base de datos creada exitosamente!"
    echo ""
}

main "$@"
