//! # Broker Integration Module
//!
//! High-performance broker integration for trading and market data connectivity.
//! Provides adapters and clients for connecting to various trading platforms
//! using their native protocols including FIX, REST APIs, and WebSocket connections.
//!
//! ## Architecture
//!
//! The broker integration follows a modular design with standardized interfaces:
//!
//! ```text
//! ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
//! │   Application   │────│  Broker Factory │────│  Protocol Layer │
//! │   Trading Logic │    │  & Adapters     │    │  (FIX/REST/WS)  │
//! └─────────────────┘    └─────────────────┘    └─────────────────┘
//!          │                       │                       │
//!          ▼                       ▼                       ▼
//! ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
//! │   Order Flow    │    │   Data Adapter  │    │   Connection    │
//! │   Management    │    │   Layer         │    │   Management    │
//! └─────────────────┘    └─────────────────┘    └─────────────────┘
//! ```
//!
//! ## Supported Brokers
//!
//! ### Interactive Brokers (TWS API)
//! - **Protocol**: TWS API over TCP socket
//! - **Features**: Real-time data, order management, account info
//! - **Markets**: Global equities, futures, forex, options
//! - **Latency**: Medium (~10-50ms)
//!
//! ### ICMarkets (FIX 4.4)
//! - **Protocol**: Financial Information eXchange (FIX) 4.4
//! - **Features**: High-frequency trading, ECN access
//! - **Markets**: Forex, CFDs, commodities
//! - **Latency**: Low (~1-5ms)
//!
//! ### Future Integrations
//! - **Alpaca**: Commission-free equity trading
//! - **TD Ameritrade**: Retail trading platform
//! - **IBKR Pro**: Enhanced Interactive Brokers
//!
//! ## Design Patterns
//!
//! ### Adapter Pattern
//! Each broker has a specific adapter that translates between the broker's
//! native protocol and our standardized internal interfaces.
//!
//! ### Factory Pattern
//! The `BrokerFactory` creates appropriate client instances based on
//! configuration, enabling runtime broker selection.
//!
//! ### Strategy Pattern
//! Different connection strategies (persistent, reconnecting, etc.) can be
//! plugged in based on requirements.
//!
//! ## Usage Examples
//!
//! ```rust
//! use data::brokers::{BrokerFactory, BrokerType, InteractiveBrokersAdapter, IBConfig};
//!
//! // Direct adapter usage
//! let ib_config = IBConfig {
//!     host: "127.0.0.1".to_string(),
//!     port: 7497,
//!     client_id: 1,
//!     // ... other config
//! };
//! let mut ib_adapter = InteractiveBrokersAdapter::new(ib_config);
//! ib_adapter.connect().await?;
//!
//! // Factory-based creation (future)
//! // let client = BrokerFactory::create_client(
//! //     BrokerType::InteractiveBrokers,
//! //     serde_json::to_value(ib_config)?
//! // ).await?;
//! ```
//!
//! ## Configuration
//!
//! Broker configurations are managed through the central config system:
//!
//! ```toml
//! [data.interactive_brokers]
//! host = "127.0.0.1"
//! port = 7497
//! client_id = 1
//! timeout_seconds = 30
//!
//! [data.icmarkets]
//! host = "fix-demo.icmarkets.com"
//! port = 9880
//! username = "${ICMARKETS_USERNAME}"
//! password = "${ICMARKETS_PASSWORD}"
//! ```
//!
//! ## Error Handling
//!
//! All broker operations return `Result<T, DataError>` for consistent error
//! handling across different broker implementations.
//!
//! ## Performance Considerations
//!
//! - **Connection Pooling**: Reuse connections where possible
//! - **Async Operations**: All I/O is non-blocking
//! - **Batching**: Group related operations to reduce latency
//! - **Circuit Breakers**: Automatic failover and recovery
//!
//! ## Architecture Note
//!
//! Core trading clients have been moved to the `core` module for the monolithic
//! architecture. This module now focuses on data-specific broker adapters and
//! connection management.

pub mod common;
pub mod interactive_brokers;

// Re-export commonly used types for convenient access
// Note: Using direct imports from common crate instead of broker-specific types

/// Re-export Interactive Brokers adapter and configuration
pub use interactive_brokers::{IBConfig, InteractiveBrokersAdapter};

/// Re-export common broker client trait
pub use common::BrokerClient;

// Create alias for BrokerAdapter (used in examples)
// TODO: Re-enable when BrokerClient trait is implemented
// /// Type alias for boxed broker client trait objects
// ///
// /// Provides a convenient way to work with different broker implementations
// /// through a common interface without knowing the specific type at compile time.
// pub type BrokerAdapter = Box<dyn BrokerClient>;

/// Enumeration of supported broker types and their protocols.
///
/// Each variant represents a different broker platform with its own
/// connectivity requirements, protocols, and capabilities.
///
/// # Protocol Details
///
/// - **ICMarkets**: `FIX` 4.4 protocol for institutional-grade trading
/// - **InteractiveBrokers**: TWS API for retail and professional trading
/// - **Alpaca**: REST API for commission-free equity trading
/// - **Mock**: In-memory broker simulation for testing
///
/// # Selection Criteria
///
/// Choose broker based on:
/// - **Latency Requirements**: ICMarkets for HFT, others for regular trading
/// - **Market Access**: Geographic and asset class coverage
/// - **Cost Structure**: Commission rates and minimum account sizes
/// - **API Capabilities**: Order types, data feeds, and functionality
///
/// # Examples
///
/// ```rust
/// use data::brokers::BrokerType;
///
/// // Select broker based on trading style
/// let hft_broker = BrokerType::ICMarkets;     // High-frequency trading
/// let retail_broker = BrokerType::InteractiveBrokers; // Retail trading
/// let test_broker = BrokerType::Mock;         // Development/testing
/// ```
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum BrokerType {
    /// ICMarkets `FIX` 4.4 protocol integration
    ///
    /// Professional ECN broker with direct market access via `FIX` protocol.
    /// Optimized for high-frequency trading with sub-millisecond latency.
    /// Supports forex, CFDs, and commodities trading.
    ICMarkets,

    /// Interactive Brokers TWS API integration
    ///
    /// Comprehensive trading platform with global market access.
    /// Uses proprietary TWS API for orders, data, and account management.
    /// Supports equities, options, futures, forex, and bonds.
    InteractiveBrokers,

    /// Alpaca REST API integration (future)
    ///
    /// Commission-free stock trading platform with modern REST API.
    /// Designed for algorithmic trading with paper trading support.
    /// US equities and crypto trading.
    Alpaca,

    /// Mock broker for testing and simulation
    ///
    /// In-memory broker simulator for development and backtesting.
    /// Provides realistic order fills and market data simulation
    /// without real money or external connections.
    Mock,
}

/// Factory for creating broker client instances.
///
/// Provides a centralized way to instantiate broker clients based on
/// configuration and broker type. Handles the complexity of different
/// broker initialization requirements and provides a uniform interface.
///
/// # Design Benefits
///
/// - **Abstraction**: Hide broker-specific initialization details
/// - **Configuration**: Centralized config-driven client creation
/// - **Extensibility**: Easy addition of new broker types
/// - **Testing**: Simplified mock broker injection
///
/// # Future Implementation
///
/// The factory will support dynamic broker client creation once the
/// `BrokerClient` trait is fully implemented across all broker types.
///
/// # Examples
///
/// ```rust
/// use data::brokers::{BrokerFactory, BrokerType};
/// use serde_json::json;
///
/// // Future usage (when trait is implemented)
/// // let config = json!({
/// //     "host": "127.0.0.1",
/// //     "port": 7497,
/// //     "client_id": 1
/// // });
/// //
/// // let client = BrokerFactory::create_client(
/// //     BrokerType::InteractiveBrokers,
/// //     config
/// // ).await?;
/// ```
pub struct BrokerFactory;

impl BrokerFactory {
    /// Validate broker configuration for the specified broker type.
    ///
    /// Checks that the provided configuration contains all required fields
    /// for the specified broker type before attempting to create a client.
    ///
    /// # Parameters
    ///
    /// * `broker_type` - The type of broker to validate configuration for
    /// * `config` - JSON configuration object to validate
    ///
    /// # Returns
    ///
    /// `Ok(())` if configuration is valid, `Err(String)` with details if invalid.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use data::brokers::{BrokerFactory, BrokerType};
    /// use serde_json::json;
    ///
    /// let config = json!({
    ///     "host": "127.0.0.1",
    ///     "port": 7497,
    ///     "client_id": 1
    /// });
    ///
    /// let result = BrokerFactory::validate_config(
    ///     &BrokerType::InteractiveBrokers,
    ///     &config
    /// );
    /// assert!(result.is_ok());
    /// ```
    pub fn validate_config(
        broker_type: &BrokerType,
        config: &serde_json::Value,
    ) -> Result<(), String> {
        match broker_type {
            BrokerType::ICMarkets => {
                let required_fields = ["host", "port", "username", "password"];
                for field in &required_fields {
                    if config.get(field).is_none() {
                        return Err(format!("Missing required field '{}' for ICMarkets", field));
                    }
                }
                Ok(())
            },
            BrokerType::InteractiveBrokers => {
                let required_fields = ["host", "port", "client_id"];
                for field in &required_fields {
                    if config.get(field).is_none() {
                        return Err(format!(
                            "Missing required field '{}' for Interactive Brokers",
                            field
                        ));
                    }
                }
                Ok(())
            },
            BrokerType::Alpaca => {
                let required_fields = ["api_key", "secret_key", "base_url"];
                for field in &required_fields {
                    if config.get(field).is_none() {
                        return Err(format!("Missing required field '{}' for Alpaca", field));
                    }
                }
                Ok(())
            },
            BrokerType::Mock => {
                // Mock broker requires minimal configuration
                Ok(())
            },
        }
    }

    /// Get the default configuration template for a broker type.
    ///
    /// Returns a JSON template with all required and optional fields
    /// for the specified broker type, with example or default values.
    ///
    /// # Parameters
    ///
    /// * `broker_type` - The broker type to get template for
    ///
    /// # Returns
    ///
    /// JSON object with configuration template.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use data::brokers::{BrokerFactory, BrokerType};
    ///
    /// let template = BrokerFactory::get_config_template(&BrokerType::InteractiveBrokers);
    /// println!("IB Config Template: {}", serde_json::to_string_pretty(&template).unwrap());
    /// ```
    pub fn get_config_template(broker_type: &BrokerType) -> serde_json::Value {
        match broker_type {
            BrokerType::ICMarkets => serde_json::json!({
                "host": "fix-demo.icmarkets.com",
                "port": 9880,
                "username": "${ICMARKETS_USERNAME}",
                "password": "${ICMARKETS_PASSWORD}",
                "sender_comp_id": "CLIENT",
                "target_comp_id": "ICMARKETS",
                "heartbeat_interval": 30,
                "timeout_seconds": 30
            }),
            BrokerType::InteractiveBrokers => serde_json::json!({
                "host": "127.0.0.1",
                "port": 7497,
                "client_id": 1,
                "account_id": "DU123456",
                "timeout_seconds": 30,
                "heartbeat_interval": 30,
                "max_reconnect_attempts": 5,
                "request_timeout": 30
            }),
            BrokerType::Alpaca => serde_json::json!({
                "api_key": "${ALPACA_API_KEY}",
                "secret_key": "${ALPACA_SECRET_KEY}",
                "base_url": "https://paper-api.alpaca.markets",
                "data_url": "https://data.alpaca.markets",
                "timeout_seconds": 30
            }),
            BrokerType::Mock => serde_json::json!({
                "initial_balance": 100000.0,
                "latency_ms": 10,
                "fill_rate": 0.99
            }),
        }
    }

    // TODO: Uncomment when BrokerClient trait is restored
    /*
    /// Create a broker client based on configuration.
    ///
    /// Instantiates the appropriate broker client implementation based on
    /// the broker type and configuration provided. Validates configuration
    /// before attempting to create the client.
    ///
    /// # Parameters
    ///
    /// * `broker_type` - Type of broker client to create
    /// * `config` - JSON configuration object with broker-specific settings
    ///
    /// # Returns
    ///
    /// Boxed broker client implementing the `BrokerClient` trait.
    ///
    /// # Errors
    ///
    /// Returns `DataError` if:
    /// - Configuration is invalid or missing required fields
    /// - Broker type is not yet implemented
    /// - Client initialization fails
    ///
    /// # Examples
    ///
    /// ```rust
    /// use data::brokers::{BrokerFactory, BrokerType};
    /// use serde_json::json;
    ///
    /// let config = json!({
    ///     "host": "127.0.0.1",
    ///     "port": 7497,
    ///     "client_id": 1
    /// });
    ///
    /// let client = BrokerFactory::create_client(
    ///     BrokerType::InteractiveBrokers,
    ///     config
    /// ).await?;
    /// ```
    pub async fn create_client(
        broker_type: BrokerType,
        config: serde_json::Value
    ) -> crate::Result<Box<dyn BrokerClient>> {
        // Validate configuration first
        Self::validate_config(&broker_type, &config)
            .map_err(|e| crate::DataError::configuration(&e))?;

        match broker_type {
            BrokerType::ICMarkets => {
                let icmarkets_config: ICMarketsConfig = serde_json::from_value(config)
                    .map_err(|e| crate::DataError::configuration(&format!("Invalid ICMarkets config: {}", e)))?;
                let client = ICMarketsClient::new(icmarkets_config);
                Ok(Box::new(client))
            }
            BrokerType::InteractiveBrokers => {
                let ib_config: IBConfig = serde_json::from_value(config)
                    .map_err(|e| crate::DataError::configuration(&format!("Invalid IB config: {}", e)))?;
                let client = InteractiveBrokersAdapter::new(ib_config);
                Ok(Box::new(client))
            }
            BrokerType::Alpaca => {
                Err(crate::DataError::configuration("Alpaca broker not yet implemented"))
            }
            BrokerType::Mock => {
                Err(crate::DataError::configuration("Mock broker not yet implemented"))
            }
        }
    }
    */
}
