mod analytics;
mod auth;
mod contingent;
mod data_fetcher;
mod db;
mod engine;
mod error;
mod exchanges;
mod feeds;
mod kelly;
mod markov;
mod mm;
mod orderbook;
mod orders;
mod parity;
mod positions;
mod quant;
mod rate_limit;
mod risk;
mod signal;
mod simulation;
mod types;

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();
    });
}

/// 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>()?;

    // 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)?;

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

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

    Ok(())
}
