//! Data interface traits for the core trading engine
//!
//! This module defines traits that external data providers must implement
//! to work with the core trading engine. This allows core to remain independent
//! while still being able to work with different data sources.

// OrderEvent replaced with MarketDataEvent for simplicity
// Re-export MarketDataEvent for external use
use async_trait::async_trait;
use std::fmt::Debug;
use tokio::sync::broadcast;

pub use common::MarketDataEvent;
use common::{Execution, OrderStatus, Position};

// Use canonical QuoteEvent from common crate

// TradeEvent functionality removed - no longer available without data crate dependency

// OrderBookEvent moved to common::types::OrderBookEvent

// Using canonical OrderEvent from crate::types::events

/// Subscription request for market data
#[derive(Debug, Clone)]
/// Subscription
///
/// Auto-generated documentation placeholder - enhance with specifics
pub struct Subscription {
    /// Symbols
    pub symbols: Vec<String>,
    /// Data Types
    pub data_types: Vec<DataType>,
    /// Exchanges
    pub exchanges: Option<Vec<String>>,
    /// Extended Hours
    pub extended_hours: bool,
}

/// Data type for subscription
#[derive(Debug, Clone)]
/// DataType
///
/// Auto-generated documentation placeholder - enhance with specifics
pub enum DataType {
    // Trades variant
    Trades,
    // Quotes variant
    Quotes,
    // OrderBook variant
    OrderBook,
    // Bars variant
    Bars,
}

/// Trait for data providers that can supply market data
#[async_trait]
/// DataProvider
///
/// Auto-generated documentation placeholder - enhance with specifics
pub trait DataProvider: Send + Sync + Debug {
    /// Subscribe to market data for given symbols
    async fn subscribe_market_data(&self, subscription: Subscription) -> Result<(), String>;

    /// Get market data event stream
    fn subscribe_market_data_events(&self) -> broadcast::Receiver<MarketDataEvent>;

    /// Get order update event stream
    fn subscribe_order_update_events(&self) -> broadcast::Receiver<MarketDataEvent>;
}

/// Unified broker interface trait - THE ONLY BROKER TRAIT
#[async_trait]
/// BrokerInterface
///
/// Auto-generated documentation placeholder - enhance with specifics
pub trait BrokerInterface: Send + Sync + Debug {
    /// Connect to the broker
    async fn connect(&mut self) -> Result<(), BrokerError>;

    /// Disconnect from the broker
    async fn disconnect(&mut self) -> Result<(), BrokerError>;

    /// Check if connected to the broker
    fn is_connected(&self) -> bool;

    /// Check connection status
    fn connection_status(&self) -> BrokerConnectionStatus;

    /// Submit an order to the broker
    async fn submit_order(&self, order: &TradingOrder) -> Result<String, BrokerError>;

    /// Cancel an order
    async fn cancel_order(&self, broker_order_id: &str) -> Result<(), BrokerError>;

    /// Modify existing order
    async fn modify_order(
        &self,
        broker_order_id: &str,
        new_order: &TradingOrder,
    ) -> Result<(), BrokerError>;

    /// Get order status
    async fn get_order_status(&self, broker_order_id: &str) -> Result<OrderStatus, BrokerError>;

    /// Get account information
    async fn get_account_info(
        &self,
    ) -> Result<std::collections::HashMap<String, String>, BrokerError>;

    /// Get current positions
    async fn get_positions(&self) -> Result<Vec<Position>, BrokerError>;

    /// Subscribe to execution reports
    async fn subscribe_executions(
        &self,
    ) -> Result<tokio::sync::mpsc::Receiver<Execution>, BrokerError>;

    /// Get broker name
    fn broker_name(&self) -> &str;

    /// Send heartbeat to maintain connection
    async fn send_heartbeat(&self) -> Result<(), BrokerError>;

    /// Reconnect to broker after connection loss
    async fn reconnect(&self) -> Result<(), BrokerError>;
}

use crate::trading_operations::TradingOrder;

/// Broker connection status
#[derive(Debug, Clone, PartialEq, Eq)]
/// BrokerConnectionStatus
///
/// Auto-generated documentation placeholder - enhance with specifics
pub enum BrokerConnectionStatus {
    // Connected variant
    Connected,
    // Disconnected variant
    Disconnected,
    // Connecting variant
    Connecting,
    // Reconnecting variant
    Reconnecting,
    // Error variant
    Error(String),
}

/// Broker-specific errors
#[derive(Debug, Clone, thiserror::Error)]
/// BrokerError
///
/// Auto-generated documentation placeholder - enhance with specifics
pub enum BrokerError {
    #[error("Connection failed: {0}")]
    // ConnectionFailed variant
    ConnectionFailed(String),

    #[error("Authentication failed: {0}")]
    // AuthenticationFailed variant
    AuthenticationFailed(String),

    #[error("Order submission failed: {0}")]
    // OrderSubmissionFailed variant
    OrderSubmissionFailed(String),

    #[error("Order not found: {0}")]
    // OrderNotFound variant
    OrderNotFound(String),

    #[error("Invalid order: {0}")]
    // InvalidOrder variant
    InvalidOrder(String),

    #[error("Broker not available: {0}")]
    // BrokerNotAvailable variant
    BrokerNotAvailable(String),

    #[error("Protocol error: {0}")]
    // ProtocolError variant
    ProtocolError(String),

    #[error("Rate limit exceeded: {0}")]
    // RateLimitExceeded variant
    RateLimitExceeded(String),

    #[error("Internal error: {0}")]
    // InternalError variant
    InternalError(String),

    #[error("FIX protocol error: {0}")]
    // FixProtocol variant
    FixProtocol(String),

    #[error("Timeout error: {0}")]
    // Timeout variant
    Timeout(String),

    #[error("Message parsing error: {0}")]
    // MessageParsing variant
    MessageParsing(String),
}

// ExecutionReport renamed to Execution - using canonical type from common::types
// Re-export Execution as ExecutionReport for broker interfaces
// Removed pub use - import Execution and Position directly where needed
