-- ============================================================================
-- SCHEMA: trading
-- TABLE: symbols
-- DESCRIPTION: Simbolos/instrumentos habilitados para trading por tenant
-- VERSION: 1.0.0
-- CREATED: 2026-01-16
-- SPRINT: Sprint 3 - DDL Implementation Roadmap Q1-2026
-- ============================================================================

-- Crear schema si no existe
CREATE SCHEMA IF NOT EXISTS trading;

-- Grant usage
GRANT USAGE ON SCHEMA trading TO trading_app;
GRANT USAGE ON SCHEMA trading TO trading_readonly;

-- ============================================================================
-- ENUMS COMPARTIDOS DEL SCHEMA TRADING
-- ============================================================================

-- Enum para direccion de trade
DO $$ BEGIN
    CREATE TYPE trading.trade_direction AS ENUM (
        'long',             -- Compra / Buy
        'short'             -- Venta / Sell
    );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

-- Enum para estado de posicion
DO $$ BEGIN
    CREATE TYPE trading.position_status AS ENUM (
        'pending',          -- Pendiente de ejecucion
        'open',             -- Posicion abierta
        'closed',           -- Cerrada manualmente
        'stopped',          -- Cerrada por stop loss
        'target_hit',       -- Cerrada por take profit
        'expired',          -- Expirada
        'cancelled'         -- Cancelada antes de ejecutar
    );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

-- Enum para tipo de orden
DO $$ BEGIN
    CREATE TYPE trading.order_type AS ENUM (
        'market',           -- Orden de mercado
        'limit',            -- Orden limitada
        'stop',             -- Stop order
        'stop_limit'        -- Stop limit order
    );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

-- Enum para timeframe
DO $$ BEGIN
    CREATE TYPE trading.timeframe AS ENUM (
        'M1', 'M5', 'M15', 'M30',    -- Minutos
        'H1', 'H4',                   -- Horas
        'D1', 'W1', 'MN'              -- Dia, Semana, Mes
    );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

-- ============================================================================
-- TABLA: symbols
-- Simbolos habilitados por tenant (copia de market_data.tickers con config tenant)
-- ============================================================================

CREATE TABLE IF NOT EXISTS trading.symbols (
    -- Identificadores
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,
    ticker_id UUID NOT NULL REFERENCES market_data.tickers(id),

    -- Datos del simbolo (denormalizados para performance)
    symbol VARCHAR(20) NOT NULL,
    name VARCHAR(200),
    type market_data.instrument_type,

    -- Configuracion por tenant
    is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
    is_tradeable BOOLEAN NOT NULL DEFAULT TRUE,
    is_visible BOOLEAN NOT NULL DEFAULT TRUE,

    -- Limites especificos del tenant
    min_lot_size DECIMAL(10, 4),
    max_lot_size DECIMAL(10, 4),
    max_position_size DECIMAL(15, 2),               -- Tamaño maximo de posicion en USD
    max_daily_volume DECIMAL(15, 2),                -- Volumen diario maximo

    -- Spread markup (si el tenant agrega spread)
    spread_markup_pips DECIMAL(10, 4) DEFAULT 0,

    -- Comisiones del tenant
    commission_per_lot DECIMAL(10, 4) DEFAULT 0,
    commission_percent DECIMAL(5, 4) DEFAULT 0,

    -- Margen requerido (override del default)
    margin_required_percent DECIMAL(5, 2),
    max_leverage INTEGER,

    -- Trading hours override
    custom_trading_hours JSONB,

    -- Categorias/tags del tenant
    categories VARCHAR(50)[],
    tags VARCHAR(50)[],
    display_order INTEGER DEFAULT 999,

    -- Estadisticas del tenant
    trade_count INTEGER NOT NULL DEFAULT 0,
    total_volume DECIMAL(20, 4) NOT NULL DEFAULT 0,
    last_trade_at TIMESTAMPTZ,

    -- Metadata
    metadata JSONB DEFAULT '{}'::JSONB,

    -- Timestamps
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    -- Constraints
    CONSTRAINT symbols_unique_per_tenant UNIQUE (tenant_id, ticker_id),
    CONSTRAINT symbols_unique_symbol_per_tenant UNIQUE (tenant_id, symbol)
);

COMMENT ON TABLE trading.symbols IS
'Simbolos habilitados para trading por tenant con configuracion personalizada';

COMMENT ON COLUMN trading.symbols.spread_markup_pips IS
'Pips adicionales de spread que el tenant agrega al precio del broker';

-- Indices
CREATE INDEX IF NOT EXISTS idx_symbols_tenant
    ON trading.symbols(tenant_id);

CREATE INDEX IF NOT EXISTS idx_symbols_ticker
    ON trading.symbols(ticker_id);

CREATE INDEX IF NOT EXISTS idx_symbols_symbol
    ON trading.symbols(tenant_id, symbol);

CREATE INDEX IF NOT EXISTS idx_symbols_enabled
    ON trading.symbols(tenant_id, is_enabled, is_tradeable)
    WHERE is_enabled = TRUE AND is_tradeable = TRUE;

CREATE INDEX IF NOT EXISTS idx_symbols_type
    ON trading.symbols(tenant_id, type);

-- GIN index para categorias
CREATE INDEX IF NOT EXISTS idx_symbols_categories_gin
    ON trading.symbols USING GIN (categories);

-- Trigger para updated_at
CREATE OR REPLACE FUNCTION trading.update_trading_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS symbol_updated_at ON trading.symbols;
CREATE TRIGGER symbol_updated_at
    BEFORE UPDATE ON trading.symbols
    FOR EACH ROW
    EXECUTE FUNCTION trading.update_trading_timestamp();

-- Trigger para sincronizar datos del ticker
CREATE OR REPLACE FUNCTION trading.sync_symbol_from_ticker()
RETURNS TRIGGER AS $$
BEGIN
    SELECT symbol, name, type
    INTO NEW.symbol, NEW.name, NEW.type
    FROM market_data.tickers
    WHERE id = NEW.ticker_id;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS symbol_sync ON trading.symbols;
CREATE TRIGGER symbol_sync
    BEFORE INSERT OR UPDATE OF ticker_id ON trading.symbols
    FOR EACH ROW
    EXECUTE FUNCTION trading.sync_symbol_from_ticker();

-- Vista de simbolos activos
CREATE OR REPLACE VIEW trading.v_active_symbols AS
SELECT
    s.id,
    s.tenant_id,
    s.ticker_id,
    s.symbol,
    s.name,
    s.type,
    t.pip_size,
    t.typical_spread_pips,
    s.spread_markup_pips,
    (COALESCE(t.typical_spread_pips, 0) + COALESCE(s.spread_markup_pips, 0)) AS total_spread_pips,
    t.current_bid,
    t.current_ask,
    s.min_lot_size,
    s.max_lot_size,
    COALESCE(s.max_leverage, t.max_leverage) AS max_leverage,
    s.display_order
FROM trading.symbols s
JOIN market_data.tickers t ON s.ticker_id = t.id
WHERE s.is_enabled = TRUE
  AND s.is_tradeable = TRUE
  AND t.status = 'active'
ORDER BY s.display_order, s.symbol;

-- RLS Policy para multi-tenancy
ALTER TABLE trading.symbols ENABLE ROW LEVEL SECURITY;

CREATE POLICY symbols_tenant_isolation ON trading.symbols
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

-- Grants
GRANT SELECT, INSERT, UPDATE, DELETE ON trading.symbols TO trading_app;
GRANT SELECT ON trading.symbols TO trading_readonly;
GRANT SELECT ON trading.v_active_symbols TO trading_app;
