//! Trading enumeration types
//!
//! Canonical definitions for order types, broker types, order status,
//! order side, currency, and time-in-force.

use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::fmt;

// =============================================================================
// ORDER TYPES (Moved from trading_engine)
// =============================================================================

/// Order type specifying execution behavior - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderType {
    /// Market order - executes immediately at current market price
    Market,
    /// Limit order - executes only at specified price or better
    Limit,
    /// Stop order - becomes market order when stop price is reached
    Stop,
    /// Stop-limit order - becomes limit order when stop price is reached
    StopLimit,
    /// Iceberg order - large order split into smaller visible portions
    Iceberg,
    /// Trailing stop order - stop price adjusts with favorable price movement
    TrailingStop,
    /// Hidden order - not displayed in order book
    Hidden,
}

impl fmt::Display for OrderType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Market => write!(f, "MARKET"),
            Self::Limit => write!(f, "LIMIT"),
            Self::Stop => write!(f, "STOP"),
            Self::StopLimit => write!(f, "STOP_LIMIT"),
            Self::Iceberg => write!(f, "ICEBERG"),
            Self::TrailingStop => write!(f, "TRAILING_STOP"),
            Self::Hidden => write!(f, "HIDDEN"),
        }
    }
}

impl Default for OrderType {
    /// Returns the default order type (Market)
    fn default() -> Self {
        Self::Market
    }
}

impl TryFrom<i32> for OrderType {
    type Error = String;

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(OrderType::Market),
            1 => Ok(OrderType::Limit),
            2 => Ok(OrderType::Stop),
            3 => Ok(OrderType::StopLimit),
            4 => Ok(OrderType::Iceberg),
            5 => Ok(OrderType::TrailingStop),
            6 => Ok(OrderType::Hidden),
            _ => Err(format!("Invalid OrderType: {}", value)),
        }
    }
}

/// Supported broker types - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BrokerType {
    /// Interactive Brokers TWS/API
    InteractiveBrokers,
    /// IC Markets FIX API
    ICMarkets,
    /// Paper trading simulation
    PaperTrading,
    /// Demo/Test broker
    Demo,
}

impl Default for BrokerType {
    /// Returns the default broker type (`InteractiveBrokers`)
    fn default() -> Self {
        Self::InteractiveBrokers
    }
}

/// Order status throughout its lifecycle - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderStatus {
    /// Order has been created but not yet submitted to broker
    Created,
    /// Order has been submitted to broker for execution
    Submitted,
    /// Order has been partially executed with remaining quantity
    PartiallyFilled,
    /// Order has been completely executed
    Filled,
    /// Order was rejected by broker or exchange
    Rejected,
    /// Order was cancelled by user or system
    Cancelled,
    /// New order accepted by broker
    New,
    /// Order expired due to time restrictions
    Expired,
    /// Order is pending broker acceptance
    Pending,
    /// Order is actively working in the market
    Working,
    /// Order status is unknown or not yet determined
    Unknown,
    /// Order is temporarily suspended
    Suspended,
    /// Order cancellation is pending
    PendingCancel,
    /// Order modification is pending
    PendingReplace,
}
impl fmt::Display for OrderStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Created => write!(f, "CREATED"),
            Self::Submitted => write!(f, "SUBMITTED"),
            Self::PartiallyFilled => write!(f, "PARTIALLY_FILLED"),
            Self::Filled => write!(f, "FILLED"),
            Self::Rejected => write!(f, "REJECTED"),
            Self::Cancelled => write!(f, "CANCELLED"),
            Self::New => write!(f, "NEW"),
            Self::Expired => write!(f, "EXPIRED"),
            Self::Pending => write!(f, "PENDING"),
            Self::Working => write!(f, "WORKING"),
            Self::Unknown => write!(f, "UNKNOWN"),
            Self::Suspended => write!(f, "SUSPENDED"),
            Self::PendingCancel => write!(f, "PENDING_CANCEL"),
            Self::PendingReplace => write!(f, "PENDING_REPLACE"),
        }
    }
}

impl Default for OrderStatus {
    /// Returns the default order status (Created)
    fn default() -> Self {
        Self::Created
    }
}

impl TryFrom<i32> for OrderStatus {
    type Error = String;

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(OrderStatus::Created),
            1 => Ok(OrderStatus::Submitted),
            2 => Ok(OrderStatus::PartiallyFilled),
            3 => Ok(OrderStatus::Filled),
            4 => Ok(OrderStatus::Rejected),
            5 => Ok(OrderStatus::Cancelled),
            6 => Ok(OrderStatus::New),
            7 => Ok(OrderStatus::Expired),
            8 => Ok(OrderStatus::Pending),
            9 => Ok(OrderStatus::Working),
            10 => Ok(OrderStatus::Unknown),
            11 => Ok(OrderStatus::Suspended),
            12 => Ok(OrderStatus::PendingCancel),
            13 => Ok(OrderStatus::PendingReplace),
            _ => Err(format!("Invalid OrderStatus: {}", value)),
        }
    }
}

/// Order side - whether the order is a buy or sell - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum OrderSide {
    /// Buy order - purchasing securities
    Buy,
    /// Sell order - selling securities
    Sell,
}

impl fmt::Display for OrderSide {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Buy => write!(f, "BUY"),
            Self::Sell => write!(f, "SELL"),
        }
    }
}

impl Default for OrderSide {
    /// Returns the default order side (Buy)
    fn default() -> Self {
        Self::Buy
    }
}

impl TryFrom<i32> for OrderSide {
    type Error = String;

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(OrderSide::Buy),
            1 => Ok(OrderSide::Sell),
            _ => Err(format!("Invalid OrderSide: {}", value)),
        }
    }
}

// REMOVED: Side alias - use OrderSide directly

/// Currency enumeration - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::Type))]
pub enum Currency {
    /// US Dollar
    USD,
    /// Euro
    EUR,
    /// British Pound Sterling
    GBP,
    /// Japanese Yen
    JPY,
    /// Swiss Franc
    CHF,
    /// Canadian Dollar
    CAD,
    /// Australian Dollar
    AUD,
    /// New Zealand Dollar
    NZD,
    /// Bitcoin
    BTC,
    /// Ethereum
    ETH,
}

impl fmt::Display for Currency {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::USD => write!(f, "USD"),
            Self::EUR => write!(f, "EUR"),
            Self::GBP => write!(f, "GBP"),
            Self::JPY => write!(f, "JPY"),
            Self::CHF => write!(f, "CHF"),
            Self::CAD => write!(f, "CAD"),
            Self::AUD => write!(f, "AUD"),
            Self::NZD => write!(f, "NZD"),
            Self::BTC => write!(f, "BTC"),
            Self::ETH => write!(f, "ETH"),
        }
    }
}

impl Default for Currency {
    /// Returns the default currency (USD)
    fn default() -> Self {
        Self::USD
    }
}

/// Time in force enumeration - CANONICAL DEFINITION
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum TimeInForce {
    /// Order is valid for the current trading day only
    Day,
    /// Order remains active until explicitly cancelled
    GoodTillCancel,
    /// Order must be executed immediately or cancelled
    ImmediateOrCancel,
    /// Order must be executed completely or cancelled
    FillOrKill,
}

impl fmt::Display for TimeInForce {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Day => write!(f, "DAY"),
            Self::GoodTillCancel => write!(f, "GTC"),
            Self::ImmediateOrCancel => write!(f, "IOC"),
            Self::FillOrKill => write!(f, "FOK"),
        }
    }
}

impl Default for TimeInForce {
    /// Returns the default time in force (Day)
    fn default() -> Self {
        Self::Day
    }
}
