-- Asset Classification Schema
-- Comprehensive database schema for dynamic asset classification and trading parameters

-- Asset Classes Table - Define hierarchical asset classifications
CREATE TABLE asset_classes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    parent_id UUID REFERENCES asset_classes(id),
    classification_data JSONB NOT NULL,
    description TEXT,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create index for hierarchical queries
CREATE INDEX idx_asset_classes_parent_id ON asset_classes(parent_id);
CREATE INDEX idx_asset_classes_active ON asset_classes(is_active);
CREATE INDEX idx_asset_classes_classification ON asset_classes USING GIN(classification_data);

-- Asset Configurations Table - Pattern-based symbol classification rules
CREATE TABLE asset_configurations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    symbol_pattern VARCHAR(1000) NOT NULL,
    asset_class_data JSONB NOT NULL,
    volatility_profile JSONB NOT NULL,
    trading_parameters JSONB NOT NULL,
    priority INTEGER NOT NULL DEFAULT 100,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    trading_hours JSONB,
    settlement_config JSONB NOT NULL DEFAULT '{"settlement_days": 2, "settlement_currency": "USD", "physical_settlement": false}'::jsonb
);

-- Create indexes for performance
CREATE INDEX idx_asset_configurations_priority ON asset_configurations(priority DESC, is_active);
CREATE INDEX idx_asset_configurations_active ON asset_configurations(is_active);
CREATE INDEX idx_asset_configurations_pattern ON asset_configurations(symbol_pattern);
CREATE INDEX idx_asset_configurations_asset_class ON asset_configurations USING GIN(asset_class_data);

-- Symbol Mappings Table - Explicit symbol to asset class mappings
CREATE TABLE symbol_mappings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    symbol VARCHAR(50) NOT NULL UNIQUE,
    asset_class_data JSONB NOT NULL,
    volatility_override JSONB,
    trading_parameters_override JSONB,
    source VARCHAR(100) DEFAULT 'manual',
    confidence_score DECIMAL(3,2) DEFAULT 1.00,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    expires_at TIMESTAMP WITH TIME ZONE
);

-- Indexes for symbol lookups
CREATE INDEX idx_symbol_mappings_symbol ON symbol_mappings(upper(symbol));
CREATE INDEX idx_symbol_mappings_active ON symbol_mappings(is_active);
CREATE INDEX idx_symbol_mappings_expires ON symbol_mappings(expires_at) WHERE expires_at IS NOT NULL;

-- Volatility Profiles Table - Reusable volatility profile templates
CREATE TABLE volatility_profiles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    base_annual_volatility DECIMAL(6,4) NOT NULL,
    stress_volatility_multiplier DECIMAL(4,2) NOT NULL DEFAULT 2.0,
    intraday_pattern JSONB NOT NULL DEFAULT '[]'::jsonb,
    volatility_persistence DECIMAL(4,3) NOT NULL DEFAULT 0.85,
    jump_risk JSONB NOT NULL DEFAULT '{"jump_probability": 0.01, "jump_magnitude": 0.05, "max_jump_size": 0.15}'::jsonb,
    description TEXT,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Trading Parameters Templates Table - Reusable trading parameter sets
CREATE TABLE trading_parameters_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    position_limits JSONB NOT NULL,
    risk_thresholds JSONB NOT NULL,
    execution_config JSONB NOT NULL,
    market_making_config JSONB,
    description TEXT,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Asset Classification Cache Table - For performance optimization
CREATE TABLE asset_classification_cache (
    symbol VARCHAR(50) PRIMARY KEY,
    asset_class_data JSONB NOT NULL,
    configuration_id UUID REFERENCES asset_configurations(id),
    cached_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    expires_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + INTERVAL '1 hour'
);

-- Index for cache expiration cleanup
CREATE INDEX idx_asset_classification_cache_expires ON asset_classification_cache(expires_at);

-- Asset Classification Audit Log
CREATE TABLE asset_classification_audit (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    symbol VARCHAR(50) NOT NULL,
    old_classification JSONB,
    new_classification JSONB NOT NULL,
    changed_by VARCHAR(255),
    change_reason TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Index for audit queries
CREATE INDEX idx_asset_classification_audit_symbol ON asset_classification_audit(symbol);
CREATE INDEX idx_asset_classification_audit_created ON asset_classification_audit(created_at);

-- Configuration Change Notifications Table
CREATE TABLE config_change_notifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    notification_type VARCHAR(50) NOT NULL,
    table_name VARCHAR(100) NOT NULL,
    record_id UUID NOT NULL,
    change_data JSONB NOT NULL,
    processed BOOLEAN DEFAULT false,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Index for notification processing
CREATE INDEX idx_config_change_notifications_processed ON config_change_notifications(processed, created_at);

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

-- Apply update triggers to all configuration tables
CREATE TRIGGER update_asset_classes_updated_at BEFORE UPDATE ON asset_classes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_asset_configurations_updated_at BEFORE UPDATE ON asset_configurations FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_symbol_mappings_updated_at BEFORE UPDATE ON symbol_mappings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_volatility_profiles_updated_at BEFORE UPDATE ON volatility_profiles FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_trading_parameters_templates_updated_at BEFORE UPDATE ON trading_parameters_templates FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Notification trigger function for configuration changes
CREATE OR REPLACE FUNCTION notify_config_change()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO config_change_notifications (notification_type, table_name, record_id, change_data)
    VALUES (
        TG_OP,
        TG_TABLE_NAME,
        COALESCE(NEW.id, OLD.id),
        CASE 
            WHEN TG_OP = 'DELETE' THEN row_to_json(OLD)
            ELSE row_to_json(NEW)
        END
    );
    
    -- Send PostgreSQL NOTIFY for real-time updates
    PERFORM pg_notify('config_change', json_build_object(
        'table', TG_TABLE_NAME,
        'operation', TG_OP,
        'id', COALESCE(NEW.id, OLD.id)
    )::text);
    
    RETURN COALESCE(NEW, OLD);
END;
$$ language 'plpgsql';

-- Apply notification triggers
CREATE TRIGGER notify_asset_configurations_change AFTER INSERT OR UPDATE OR DELETE ON asset_configurations FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_symbol_mappings_change AFTER INSERT OR UPDATE OR DELETE ON symbol_mappings FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_volatility_profiles_change AFTER INSERT OR UPDATE OR DELETE ON volatility_profiles FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_trading_parameters_templates_change AFTER INSERT OR UPDATE OR DELETE ON trading_parameters_templates FOR EACH ROW EXECUTE FUNCTION notify_config_change();

-- Cache maintenance function
CREATE OR REPLACE FUNCTION cleanup_asset_classification_cache()
RETURNS void AS $$
BEGIN
    DELETE FROM asset_classification_cache WHERE expires_at < NOW();
END;
$$ language 'plpgsql';

-- Views for easier querying

-- Active Asset Configurations View
CREATE VIEW active_asset_configurations AS
SELECT 
    id,
    name,
    symbol_pattern,
    asset_class_data,
    volatility_profile,
    trading_parameters,
    priority,
    trading_hours,
    settlement_config,
    created_at,
    updated_at
FROM asset_configurations
WHERE is_active = true
ORDER BY priority DESC;

-- Symbol Classification Summary View
CREATE VIEW symbol_classification_summary AS
SELECT 
    sm.symbol,
    sm.asset_class_data,
    sm.confidence_score,
    sm.source,
    ac.name as configuration_name,
    ac.priority,
    sm.created_at
FROM symbol_mappings sm
LEFT JOIN asset_configurations ac ON sm.source = 'pattern:' || ac.id::text
WHERE sm.is_active = true;

-- Asset Class Statistics View
CREATE VIEW asset_class_statistics AS
SELECT 
    asset_class_data->>'asset_class' as asset_class,
    COUNT(*) as symbol_count,
    AVG((volatility_profile->>'base_annual_volatility')::decimal) as avg_volatility,
    MIN(created_at) as first_configured,
    MAX(updated_at) as last_updated
FROM symbol_mappings
WHERE is_active = true
GROUP BY asset_class_data->>'asset_class';

-- Insert default volatility profiles
INSERT INTO volatility_profiles (name, base_annual_volatility, stress_volatility_multiplier, volatility_persistence, jump_risk, description) VALUES
('BlueChip', 0.2500, 2.0, 0.85, '{"jump_probability": 0.01, "jump_magnitude": 0.03, "max_jump_size": 0.10}', 'Large cap, stable companies'),
('Growth', 0.3500, 2.5, 0.88, '{"jump_probability": 0.02, "jump_magnitude": 0.05, "max_jump_size": 0.15}', 'High growth stocks'),
('CryptoMajor', 0.8000, 3.0, 0.92, '{"jump_probability": 0.05, "jump_magnitude": 0.10, "max_jump_size": 0.30}', 'Major cryptocurrencies like BTC, ETH'),
('CryptoAlt', 1.2000, 4.0, 0.90, '{"jump_probability": 0.08, "jump_magnitude": 0.15, "max_jump_size": 0.50}', 'Alternative cryptocurrencies'),
('ForexMajor', 0.1200, 2.0, 0.80, '{"jump_probability": 0.005, "jump_magnitude": 0.02, "max_jump_size": 0.08}', 'Major currency pairs'),
('ForexJPY', 0.1000, 2.2, 0.82, '{"jump_probability": 0.008, "jump_magnitude": 0.025, "max_jump_size": 0.06}', 'JPY currency pairs'),
('Commodity', 0.3000, 2.8, 0.86, '{"jump_probability": 0.03, "jump_magnitude": 0.08, "max_jump_size": 0.20}', 'Commodity futures and ETFs');

-- Insert default trading parameter templates
INSERT INTO trading_parameters_templates (name, position_limits, risk_thresholds, execution_config, description) VALUES
('Conservative', 
 '{"max_position_fraction": 0.10, "max_leverage": 1.5, "concentration_limit": 0.20, "min_position_size": 100}',
 '{"var_limit": 0.02, "daily_loss_limit": 0.015, "stop_loss_threshold": 0.05, "volatility_circuit_breaker": 0.03, "max_drawdown_threshold": 0.08}',
 '{"preferred_order_types": ["Limit", "Market"], "tick_size": "0.01", "min_order_size": "1", "max_order_size": "5000", "time_in_force_default": "Day", "slippage_tolerance": 0.001}',
 'Conservative trading parameters for low-risk strategies'),
('Aggressive', 
 '{"max_position_fraction": 0.25, "max_leverage": 3.0, "concentration_limit": 0.40, "min_position_size": 500}',
 '{"var_limit": 0.08, "daily_loss_limit": 0.05, "stop_loss_threshold": 0.12, "volatility_circuit_breaker": 0.08, "max_drawdown_threshold": 0.20}',
 '{"preferred_order_types": ["Market", "Limit"], "tick_size": "0.01", "min_order_size": "1", "max_order_size": "20000", "time_in_force_default": "GTC", "slippage_tolerance": 0.003}',
 'Aggressive trading parameters for high-return strategies'),
('HighFrequency', 
 '{"max_position_fraction": 0.05, "max_leverage": 10.0, "concentration_limit": 0.15, "min_position_size": 1000}',
 '{"var_limit": 0.01, "daily_loss_limit": 0.008, "stop_loss_threshold": 0.02, "volatility_circuit_breaker": 0.01, "max_drawdown_threshold": 0.05}',
 '{"preferred_order_types": ["Limit", "Hidden"], "tick_size": "0.001", "min_order_size": "100", "max_order_size": "100000", "time_in_force_default": "IOC", "slippage_tolerance": 0.0001}',
 'High-frequency trading parameters with tight risk controls');

-- Insert some default asset configurations
INSERT INTO asset_configurations (name, symbol_pattern, asset_class_data, volatility_profile, trading_parameters, priority) VALUES
('Blue Chip US Equities',
 '^(AAPL|MSFT|GOOGL|AMZN|META|TSLA|NVDA|JPM|JNJ|V|PG|UNH|HD|BAC|DIS)$',
 '{"asset_class": "Equity", "sector": "Technology", "market_cap": "LargeCap", "region": "NorthAmerica"}',
 (SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'BlueChip'),
 (SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'Conservative'),
 100),
('Major Cryptocurrencies',
 '^(BTC|ETH|BTCUSD|ETHUSD|BTCUSDT|ETHUSDT).*$',
 '{"asset_class": "Crypto", "network": "Bitcoin", "crypto_type": "Bitcoin", "market_cap_rank": 1}',
 (SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'CryptoMajor'),
 (SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'Aggressive'),
 90),
('Major Forex Pairs',
 '^(EUR|GBP|USD|JPY|AUD|CAD|CHF)(USD|EUR|GBP|JPY)$',
 '{"asset_class": "Forex", "base": "EUR", "quote": "USD", "pair_type": "Major"}',
 (SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'ForexMajor'),
 (SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'HighFrequency'),
 80);

-- Comments for documentation
COMMENT ON TABLE asset_configurations IS 'Pattern-based asset classification configurations with trading parameters';
COMMENT ON TABLE symbol_mappings IS 'Explicit symbol to asset class mappings for fast lookup';
COMMENT ON TABLE volatility_profiles IS 'Reusable volatility profile templates for different asset types';
COMMENT ON TABLE trading_parameters_templates IS 'Reusable trading parameter configurations';
COMMENT ON TABLE asset_classification_cache IS 'Performance cache for symbol classifications';
COMMENT ON TABLE asset_classification_audit IS 'Audit trail for asset classification changes';

COMMENT ON COLUMN asset_configurations.symbol_pattern IS 'Regular expression pattern for matching symbols';
COMMENT ON COLUMN asset_configurations.priority IS 'Pattern matching priority (higher numbers checked first)';
COMMENT ON COLUMN symbol_mappings.confidence_score IS 'Confidence score for classification (0.0-1.0)';
COMMENT ON COLUMN symbol_mappings.expires_at IS 'Optional expiration for temporary classifications';