mod acd;
mod adversarial;
mod almgren_chriss;
mod analytics;
mod belief_vol;
mod bootstrap;
mod breeden_litzenberger;
mod auth;
mod bars;
mod bocpd;
mod char_pricing;
mod collector;
mod contingent;
mod copula;
mod correlation_regime;
mod cross_impact;
mod data_fetcher;
mod db;
mod elastic_net;
mod engine;
mod entropy_pool;
mod error;
mod evolution;
mod exchanges;
mod feeds;
mod fracdiff;
mod garleanu_pedersen;
mod graph_analysis;
mod hedge;
mod hjb_mm;
mod hrp;
mod index;
mod invariance;
mod kalman;
mod kelly;
mod labeling;
mod lead_lag;
mod liquidity_agg;
mod logit;
mod markov;
mod mm;
mod multi_leg;
mod optimal_stop;
mod options_overlay;
mod orderbook;
mod orders;
mod parity;
mod particle_filter;
mod portable_alpha;
mod positions;
mod quant;
mod queue_model;
mod rate_limit;
mod rewards;
mod risk;
mod robust_portfolio;
mod signal;
mod simulation;
mod triggers;
mod types;
mod vine_copula;
mod vol_signature;

use pyo3::prelude::*;
use std::sync::Once;

static TRACING_INIT: Once = Once::new();

/// Initialize tracing subscriber (once).
/// Respects HORIZON_LOG env var (e.g., HORIZON_LOG=debug).
/// Defaults to "warn" if not set.
fn init_tracing() {
    TRACING_INIT.call_once(|| {
        let filter = tracing_subscriber::EnvFilter::try_from_env("HORIZON_LOG")
            .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("warn"));
        tracing_subscriber::fmt()
            .with_env_filter(filter)
            .with_target(true)
            .compact()
            .try_init()
            .ok();
    });
}

#[pyfunction]
fn auth_current_tier() -> String {
    crate::auth::current_tier().to_string()
}

#[pyfunction]
fn auth_require_pro() -> PyResult<()> {
    crate::auth::require_pro().map_err(|e| pyo3::exceptions::PyPermissionError::new_err(e.to_string()))
}

#[pyfunction]
fn auth_require_ultra() -> PyResult<()> {
    crate::auth::require_ultra().map_err(|e| pyo3::exceptions::PyPermissionError::new_err(e.to_string()))
}

/// Horizon — Prediction Market Trading SDK (Rust core)
#[pymodule]
fn _horizon(m: &Bound<'_, PyModule>) -> PyResult<()> {
    // Initialize tracing on module import
    init_tracing();

    // Enums
    m.add_class::<types::Side>()?;
    m.add_class::<types::OrderSide>()?;
    m.add_class::<types::OrderType>()?;
    m.add_class::<types::TimeInForce>()?;
    m.add_class::<types::OrderStatus>()?;
    m.add_class::<types::AlertLevel>()?;

    // Data types
    m.add_class::<types::Market>()?;
    m.add_class::<types::Quote>()?;
    m.add_class::<types::RiskConfig>()?;
    m.add_class::<types::OrderRequest>()?;
    m.add_class::<types::Order>()?;
    m.add_class::<types::Position>()?;
    m.add_class::<types::Fill>()?;
    m.add_class::<types::EngineStatus>()?;
    m.add_class::<types::TriggerType>()?;
    m.add_class::<types::ContingentOrder>()?;

    // Feed types
    m.add_class::<feeds::FeedSnapshot>()?;
    m.add_class::<feeds::FeedMetrics>()?;
    m.add_class::<orderbook::OrderbookSnapshot>()?;

    // Multi-outcome event types
    m.add_class::<types::Outcome>()?;
    m.add_class::<types::Event>()?;

    // Parity / Arbitrage types
    m.add_class::<parity::ParityResult>()?;
    m.add_class::<parity::ArbitrageOpportunity>()?;
    m.add_class::<parity::EventArbitrageOpportunity>()?;
    m.add_class::<parity::ParityArbitrageOpportunity>()?;
    m.add_class::<parity::LatencyArbOpportunity>()?;

    // Stat arb functions
    m.add_function(wrap_pyfunction!(parity::cointegration_test, m)?)?;
    m.add_function(wrap_pyfunction!(parity::spread_zscore, m)?)?;

    // Engine
    m.add_class::<engine::Engine>()?;

    // Kelly criterion functions (standalone for max flexibility)
    kelly::register(m)?;

    // Signal combination functions
    signal::register(m)?;

    // Market making functions
    mm::register(m)?;

    // Monte Carlo simulation
    simulation::register(m)?;

    // Analytics (calibration, log-loss, edge decay)
    analytics::register(m)?;

    // Historical data fetching
    data_fetcher::register(m)?;

    // Market data collector
    collector::register(m)?;

    // Markov regime detection
    markov::register(m)?;

    // Quantitative analytics
    quant::register(m)?;

    // Information-driven bars (Lopez de Prado Ch. 2)
    bars::register(m)?;

    // Triple barrier labeling (Lopez de Prado Ch. 2-3)
    labeling::register(m)?;

    // Fractional differentiation (Lopez de Prado AFML Ch. 5)
    fracdiff::register(m)?;

    // Hierarchical Risk Parity + Marcenko-Pastur denoising
    hrp::register(m)?;

    // Polymarket liquidity rewards
    rewards::register(m)?;

    // Kalman filter suite (standard + unscented)
    kalman::register(m)?;

    // Particle filter / Sequential Monte Carlo
    particle_filter::register(m)?;

    // Bayesian Online Change Point Detection
    bocpd::register(m)?;

    // Lead-lag detection
    lead_lag::register(m)?;

    // Graph/network analysis
    graph_analysis::register(m)?;

    // Garleanu-Pedersen optimal execution
    garleanu_pedersen::register(m)?;

    // Almgren-Chriss optimal liquidation
    almgren_chriss::register(m)?;

    // Queue position modeling
    queue_model::register(m)?;

    // Copula dependence modeling
    copula::register(m)?;

    // Vine copulas for high-dimensional dependence
    vine_copula::register(m)?;

    // Cross-impact matrix estimation
    cross_impact::register(m)?;

    // Entropy pooling (Meucci)
    entropy_pool::register(m)?;

    // Robust portfolio optimization
    robust_portfolio::register(m)?;

    // Optimal stopping (Longstaff-Schwartz)
    optimal_stop::register(m)?;

    // ACD duration models
    acd::register(m)?;

    // Elastic net / LASSO / Ridge regression
    elastic_net::register(m)?;

    // Microstructure invariance
    invariance::register(m)?;

    // Volatility signature plot
    vol_signature::register(m)?;

    // Characteristic function pricing (Heston, Merton, VG)
    char_pricing::register(m)?;

    // HJB optimal market making (Avellaneda-Stoikov)
    hjb_mm::register(m)?;

    // Stock market hedging
    hedge::register(m)?;

    // Synthetic index construction
    index::register(m)?;

    // Correlation regime detection
    correlation_regime::register(m)?;

    // Portable alpha / market-neutral
    portable_alpha::register(m)?;

    // Trigger system (IFTTT)
    triggers::register(m)?;

    // Options/derivatives overlay
    options_overlay::register(m)?;

    // Cross-venue liquidity aggregation
    liquidity_agg::register(m)?;

    // Multi-leg atomic execution
    multi_leg::register(m)?;

    // Evolutionary strategy optimizer
    evolution::register(m)?;

    // Adversarial simulation
    adversarial::register(m)?;

    // Bootstrap statistical methods
    bootstrap::register(m)?;

    // Logit-space pricing
    logit::register(m)?;

    // Belief-volatility surface
    belief_vol::register(m)?;

    // Breeden-Litzenberger cross-asset probability extraction
    breeden_litzenberger::register(m)?;

    // Tier checking functions
    m.add_function(wrap_pyfunction!(auth_current_tier, m)?)?;
    m.add_function(wrap_pyfunction!(auth_require_pro, m)?)?;
    m.add_function(wrap_pyfunction!(auth_require_ultra, m)?)?;

    Ok(())
}
