#![deny(clippy::all)]

// Domain modules - core types and abstractions
pub mod domain;
pub mod events;
pub mod modes;
pub mod strategies;

// Core functionality modules
pub mod core;
pub mod orderbook;
pub mod risk;
pub mod positions;
pub mod analytics;
pub mod indicators;
pub mod backtest;

// API layer
pub mod api;

// Re-export all domain types
pub use domain::*;

// Re-export event system
pub use events::{Event, EventType, EventBus, EventHandler};

// Re-export mode types and engine trait
pub use modes::{TradingMode, TradingEngine};

// Re-export strategy framework
pub use strategies::framework::{Strategy, StrategyContext, Signal, SignalAction};

// Re-export position tracking
pub use positions::{PositionTracker, TradeRecord, ClosedTrade};

// Re-export risk management
pub use risk::{RiskLimits, RiskCheckResult, RiskMetrics, RiskEngine};

// Re-export analytics
pub use analytics::{AnalyticsEngine, PerformanceMetrics};

// Re-export indicators
pub use indicators::{Indicator, IndicatorSet};

// Re-export backtest types
pub use backtest::{BacktestEngine, BacktestResults};

// Re-export API
pub use api::TradingAPI;

// Core system traits
use async_trait::async_trait;
use chrono::{DateTime, Utc};

/// Source of market data - can be historical files, live feed, or simulated
#[async_trait]
pub trait MarketDataSource: Send + Sync {
    async fn get_next_update(&mut self) -> Option<MarketUpdate>;
    fn seek_to_time(&mut self, timestamp: DateTime<Utc>) -> Result<(), String>;
}

/// Handles order execution - can be simulated, paper, or live broker
#[async_trait]
pub trait ExecutionHandler: Send + Sync {
    async fn submit_order(&self, order: &Order) -> Result<String, String>;
    async fn cancel_order(&self, order_id: &str) -> Result<(), String>;
    async fn get_order_status(&self, order_id: &str) -> Result<OrderStatus, String>;
}

/// Provides current time - can be simulated time for backtest or real time
pub trait TimeProvider: Send + Sync {
    fn now(&self) -> DateTime<Utc>;
    fn sleep_until(&self, target: DateTime<Utc>) -> Result<(), String>;
}

/// Simulates order fills for backtest/paper trading
pub trait FillSimulator: Send + Sync {
    fn simulate_fill(&self, order: &Order, market_price: f64, spread: f64) -> Option<Fill>;
}

/// Main trading system that coordinates all components
pub struct TradingCore {
    mode: TradingMode,
    engine: Box<dyn TradingEngine>,
    event_bus: EventBus,
    orderbook_manager: OrderBookManager,
    position_tracker: PositionTracker,
    risk_engine: RiskEngine,
    analytics_engine: AnalyticsEngine,
}

impl TradingCore {
    /// Create a new trading system for the specified mode
    pub fn new(mode: TradingMode) -> Result<Self, String> {
        let engine = modes::create_engine_for_mode(&mode)?;
        let event_bus = EventBus::new();
        
        Ok(Self {
            mode,
            engine,
            event_bus,
            orderbook_manager: OrderBookManager::new(),
            position_tracker: PositionTracker::new(),
            risk_engine: RiskEngine::new(),
            analytics_engine: AnalyticsEngine::new(),
        })
    }
    
    /// Start the trading system
    pub async fn start(&mut self) -> Result<(), String> {
        self.engine.start(&mut self.event_bus).await
    }
    
    /// Stop the trading system
    pub async fn stop(&mut self) -> Result<(), String> {
        self.engine.stop().await
    }
    
    /// Get current trading mode
    pub fn mode(&self) -> &TradingMode {
        &self.mode
    }
}