-- Foxhunt HFT Trading System - Initial Database Schema
-- Model Management Configuration Tables

-- Create extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_notify";

-- Configuration table for system settings
CREATE TABLE IF NOT EXISTS config_entries (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    key VARCHAR(255) UNIQUE NOT NULL,
    value TEXT NOT NULL,
    description TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Model configuration table for ML model management
CREATE TABLE IF NOT EXISTS model_config (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name VARCHAR(255) NOT NULL,
    version VARCHAR(50) NOT NULL,
    s3_path TEXT NOT NULL,
    cache_path TEXT,
    metadata JSONB DEFAULT '{}',
    is_active BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(name, version)
);

-- Model versions table for version tracking
CREATE TABLE IF NOT EXISTS model_versions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    model_config_id UUID NOT NULL REFERENCES model_config(id) ON DELETE CASCADE,
    version VARCHAR(50) NOT NULL,
    s3_path TEXT NOT NULL,
    cache_path TEXT,
    checksum VARCHAR(64),
    size_bytes BIGINT,
    performance_metrics JSONB DEFAULT '{}',
    training_metadata JSONB DEFAULT '{}',
    is_current BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(model_config_id, version)
);

-- Trading positions
CREATE TABLE IF NOT EXISTS positions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    symbol VARCHAR(50) NOT NULL,
    quantity DECIMAL(18,8) NOT NULL,
    entry_price DECIMAL(18,8) NOT NULL,
    current_price DECIMAL(18,8),
    pnl DECIMAL(18,8),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Order history
CREATE TABLE IF NOT EXISTS orders (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    symbol VARCHAR(50) NOT NULL,
    order_type VARCHAR(20) NOT NULL,
    side VARCHAR(10) NOT NULL,
    quantity DECIMAL(18,8) NOT NULL,
    price DECIMAL(18,8) NOT NULL,
    status VARCHAR(20) NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Indexes for fast lookups

-- Config entries indexes
CREATE INDEX IF NOT EXISTS idx_config_entries_key ON config_entries(key);
CREATE INDEX IF NOT EXISTS idx_config_entries_updated_at ON config_entries(updated_at);

-- Model config indexes
CREATE INDEX IF NOT EXISTS idx_model_config_name ON model_config(name);
CREATE INDEX IF NOT EXISTS idx_model_config_active ON model_config(is_active);
CREATE INDEX IF NOT EXISTS idx_model_config_name_version ON model_config(name, version);
CREATE INDEX IF NOT EXISTS idx_model_config_updated_at ON model_config(updated_at);

-- Model versions indexes
CREATE INDEX IF NOT EXISTS idx_model_versions_config_id ON model_versions(model_config_id);
CREATE INDEX IF NOT EXISTS idx_model_versions_current ON model_versions(is_current);
CREATE INDEX IF NOT EXISTS idx_model_versions_version ON model_versions(version);
CREATE INDEX IF NOT EXISTS idx_model_versions_created_at ON model_versions(created_at);

-- Trading indexes
CREATE INDEX IF NOT EXISTS idx_positions_symbol ON positions(symbol);
CREATE INDEX IF NOT EXISTS idx_positions_created_at ON positions(created_at);
CREATE INDEX IF NOT EXISTS idx_orders_symbol ON orders(symbol);
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);

-- Update triggers for updated_at columns
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_config_entries_updated_at 
    BEFORE UPDATE ON config_entries 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_model_config_updated_at 
    BEFORE UPDATE ON model_config 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_model_versions_updated_at 
    BEFORE UPDATE ON model_versions 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_positions_updated_at 
    BEFORE UPDATE ON positions 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_orders_updated_at 
    BEFORE UPDATE ON orders 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Notification triggers for configuration hot-reload
CREATE OR REPLACE FUNCTION notify_config_change()
RETURNS TRIGGER AS $$
BEGIN
    CASE TG_OP
        WHEN 'INSERT', 'UPDATE' THEN
            PERFORM pg_notify('config_change', 
                json_build_object(
                    'operation', TG_OP,
                    'table', TG_TABLE_NAME,
                    'id', NEW.id,
                    'key', COALESCE(NEW.key, NEW.name),
                    'timestamp', extract(epoch from NOW())
                )::text
            );
            RETURN NEW;
        WHEN 'DELETE' THEN
            PERFORM pg_notify('config_change', 
                json_build_object(
                    'operation', TG_OP,
                    'table', TG_TABLE_NAME,
                    'id', OLD.id,
                    'key', COALESCE(OLD.key, OLD.name),
                    'timestamp', extract(epoch from NOW())
                )::text
            );
            RETURN OLD;
    END CASE;
END;
$$ language 'plpgsql';

-- Apply notification triggers
CREATE TRIGGER notify_config_entries_change 
    AFTER INSERT OR UPDATE OR DELETE ON config_entries
    FOR EACH ROW EXECUTE FUNCTION notify_config_change();

CREATE TRIGGER notify_model_config_change 
    AFTER INSERT OR UPDATE OR DELETE ON model_config
    FOR EACH ROW EXECUTE FUNCTION notify_config_change();

CREATE TRIGGER notify_model_versions_change 
    AFTER INSERT OR UPDATE OR DELETE ON model_versions
    FOR EACH ROW EXECUTE FUNCTION notify_config_change();

-- Initial configuration data
INSERT INTO config_entries (key, value, description) VALUES
    ('system.latency_target_ns', '14', 'Target latency in nanoseconds'),
    ('trading.max_position_size', '1000000', 'Maximum position size in base currency'),
    ('risk.var_confidence', '0.95', 'VaR confidence level'),
    ('ml.model_cache_ttl', '3600', 'Model cache TTL in seconds'),
    ('s3.model_bucket', 'foxhunt-models', 'S3 bucket for model storage'),
    ('s3.model_prefix', 'models/', 'S3 prefix for models')
ON CONFLICT (key) DO NOTHING;