-- ============================================================================
-- OrbiQuant IA - Inicialización de Esquemas
-- ============================================================================
-- Archivo: 00_init_schemas.sql
-- Descripción: Creación de esquemas y extensiones base
-- Fecha: 2025-12-05
-- ============================================================================

-- Extensiones requeridas
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";      -- Generación de UUIDs
CREATE EXTENSION IF NOT EXISTS "pgcrypto";       -- Funciones criptográficas
CREATE EXTENSION IF NOT EXISTS "pg_trgm";        -- Búsqueda de texto similar

-- ============================================================================
-- ESQUEMAS
-- ============================================================================

-- Esquema público (usuarios y configuración global)
-- Ya existe por defecto, solo documentamos
COMMENT ON SCHEMA public IS 'Usuarios, perfiles, configuración global y autenticación';

-- Esquema de educación
CREATE SCHEMA IF NOT EXISTS education;
COMMENT ON SCHEMA education IS 'Cursos, lecciones, inscripciones y contenido educativo';

-- Esquema de trading
CREATE SCHEMA IF NOT EXISTS trading;
COMMENT ON SCHEMA trading IS 'Bots, señales, estrategias y operaciones de trading';

-- Esquema de inversión
CREATE SCHEMA IF NOT EXISTS investment;
COMMENT ON SCHEMA investment IS 'Cuentas de inversión, productos y gestión de portafolios';

-- Esquema financiero
CREATE SCHEMA IF NOT EXISTS financial;
COMMENT ON SCHEMA financial IS 'Pagos, suscripciones, wallets y transacciones';

-- Esquema de machine learning
CREATE SCHEMA IF NOT EXISTS ml;
COMMENT ON SCHEMA ml IS 'Modelos ML, predicciones, features y métricas';

-- Esquema de auditoría
CREATE SCHEMA IF NOT EXISTS audit;
COMMENT ON SCHEMA audit IS 'Logs de auditoría, eventos del sistema y seguridad';

-- ============================================================================
-- TIPOS ENUMERADOS GLOBALES
-- ============================================================================

-- Estados comunes
CREATE TYPE status_enum AS ENUM ('active', 'inactive', 'pending', 'suspended', 'deleted');

-- Roles del sistema
CREATE TYPE user_role_enum AS ENUM (
    'investor',      -- Cliente final pasivo
    'trader_pro',    -- Usuario activo con herramientas
    'student',       -- Alumno de cursos
    'admin',         -- Administrador
    'risk_officer',  -- Oficial de riesgos
    'support'        -- Soporte al cliente
);

-- Perfiles de riesgo
CREATE TYPE risk_profile_enum AS ENUM ('conservative', 'moderate', 'aggressive');

-- Direcciones de trading
CREATE TYPE trade_direction_enum AS ENUM ('long', 'short');

-- Estados de orden
CREATE TYPE order_status_enum AS ENUM ('pending', 'open', 'filled', 'cancelled', 'expired');

-- Tipos de transacción financiera
CREATE TYPE transaction_type_enum AS ENUM (
    'deposit',
    'withdrawal',
    'subscription_payment',
    'course_purchase',
    'investment_deposit',
    'investment_withdrawal',
    'profit_distribution',
    'fee',
    'refund'
);

-- ============================================================================
-- FUNCIÓN PARA TIMESTAMPS AUTOMÁTICOS
-- ============================================================================

CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ language 'plpgsql';

-- ============================================================================
-- FUNCIÓN PARA AUDITORÍA AUTOMÁTICA
-- ============================================================================

CREATE OR REPLACE FUNCTION audit.log_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit.audit_logs (
        table_name,
        record_id,
        action,
        old_data,
        new_data,
        user_id,
        ip_address
    ) VALUES (
        TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME,
        COALESCE(NEW.id, OLD.id)::text,
        TG_OP,
        CASE WHEN TG_OP = 'DELETE' THEN row_to_json(OLD) ELSE NULL END,
        CASE WHEN TG_OP IN ('INSERT', 'UPDATE') THEN row_to_json(NEW) ELSE NULL END,
        current_setting('app.current_user_id', true)::uuid,
        current_setting('app.client_ip', true)
    );
    RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;
