//! Core domain types for trading
//!
//! Contains Order, Position, Execution, Price, Quantity, Money, Symbol,
//! and associated identifier types (OrderId, ExecutionId, TradeId, AccountId).
//! Also includes HftTimestamp, GenericTimestamp, and Volume alias.

use chrono::{DateTime, Utc};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::convert::TryFrom;
use std::fmt;
use std::iter::Sum;
use std::num::ParseIntError;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
use std::str::FromStr;
use uuid::Uuid;

use crate::error::{CommonError, ErrorCategory as CommonErrorCategory};
use super::{CommonTypeError, Currency, DecimalExt, OrderSide, OrderStatus, OrderType, TimeInForce};

// =============================================================================
// CORE TRADING TYPES - MIGRATED FROM TRADING_ENGINE
// =============================================================================

/// Canonical Order struct - UNIFIED DEFINITION based on Agent 1's comprehensive analysis
///
/// This represents the single source of truth for Order across all services
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::FromRow))]
pub struct Order {
    // Core Identity
    /// Unique order identifier
    pub id: OrderId,
    /// Client-provided order identifier
    pub client_order_id: Option<String>,
    /// Broker-assigned order identifier
    pub broker_order_id: Option<String>,
    /// Account identifier for the order
    pub account_id: Option<String>,

    // Trading Details
    /// Trading symbol for the order
    pub symbol: Symbol,
    /// Order side (buy or sell)
    pub side: OrderSide,
    /// Type of order (market, limit, etc.)
    pub order_type: OrderType,
    /// Current status of the order
    pub status: OrderStatus,
    /// Time in force policy
    pub time_in_force: TimeInForce,

    // Quantities & Pricing
    /// Total order quantity
    pub quantity: Quantity,
    /// Limit price for the order
    pub price: Option<Price>,
    /// Stop price for stop orders
    pub stop_price: Option<Price>,
    /// Quantity that has been filled
    pub filled_quantity: Quantity,
    /// Remaining quantity to be filled
    pub remaining_quantity: Quantity,
    /// Average execution price
    pub average_price: Option<Price>,
    /// Alias for `average_price` for database compatibility
    pub avg_fill_price: Option<Price>,
    /// Alias for `average_price` for API compatibility
    pub average_fill_price: Option<Price>,
    /// Exchange-assigned order identifier
    pub exchange_order_id: Option<String>,

    // Strategy Fields (from Agent 1)
    /// Parent order ID for iceberg/algo orders
    pub parent_id: Option<String>,
    /// Execution algorithm name
    pub execution_algorithm: Option<String>,
    /// Execution algorithm parameters stored as JSON
    pub execution_params: Value,

    // Risk Management (from Agent 1)
    /// Stop loss price for risk management
    pub stop_loss: Option<Price>,
    /// Take profit price for profit taking
    pub take_profit: Option<Price>,

    // Timestamps
    /// Order creation timestamp
    pub created_at: HftTimestamp,
    /// Last update timestamp
    pub updated_at: Option<HftTimestamp>,
    /// Order expiration timestamp
    pub expires_at: Option<HftTimestamp>,

    // Extensibility
    /// Additional order metadata stored as JSON
    pub metadata: Value,
}

impl Order {
    /// Create a new order with canonical fields
    pub fn new(
        symbol: Symbol,
        side: OrderSide,
        quantity: Quantity,
        price: Option<Price>,
        order_type: OrderType,
    ) -> Self {
        let now = HftTimestamp::now_or_zero();
        Self {
            // Core Identity
            id: OrderId::new(),
            client_order_id: None,
            broker_order_id: None,
            account_id: None,

            // Trading Details
            symbol,
            side,
            order_type,
            status: OrderStatus::Created,
            time_in_force: TimeInForce::default(),

            // Quantities & Pricing
            quantity,
            price,
            stop_price: None,
            filled_quantity: Quantity::ZERO,
            remaining_quantity: quantity,
            average_price: None,
            avg_fill_price: None,     // Database compatibility alias
            average_fill_price: None, // API compatibility alias
            exchange_order_id: None,

            // Strategy Fields
            parent_id: None,
            execution_algorithm: None,
            execution_params: serde_json::json!({}),

            // Risk Management
            stop_loss: None,
            take_profit: None,

            // Timestamps
            created_at: now,
            updated_at: None,
            expires_at: None,

            // Extensibility
            metadata: serde_json::json!({}),
        }
    }

    /// Check if the order is fully filled
    pub fn is_filled(&self) -> bool {
        self.filled_quantity == self.quantity
    }

    /// Check if the order is partially filled
    pub fn is_partially_filled(&self) -> bool {
        self.filled_quantity > Quantity::ZERO && self.filled_quantity < self.quantity
    }

    /// Calculate fill percentage
    #[allow(clippy::float_arithmetic)]
    pub fn fill_percentage(&self) -> f64 {
        if self.quantity.is_zero() {
            0.0
        } else {
            (self.filled_quantity.to_f64() / self.quantity.to_f64()) * 100.0
        }
    }

    /// Set client order ID for tracking
    pub fn with_client_order_id(mut self, client_order_id: String) -> Self {
        self.client_order_id = Some(client_order_id);
        self
    }

    /// Set account ID
    pub fn with_account_id(mut self, account_id: String) -> Self {
        self.account_id = Some(account_id);
        self
    }

    /// Set time in force
    pub const fn with_time_in_force(mut self, time_in_force: TimeInForce) -> Self {
        self.time_in_force = time_in_force;
        self
    }

    /// Set stop price
    pub const fn with_stop_price(mut self, stop_price: Price) -> Self {
        self.stop_price = Some(stop_price);
        self
    }

    /// Set execution algorithm
    pub fn with_execution_algorithm(mut self, algorithm: String) -> Self {
        self.execution_algorithm = Some(algorithm);
        self
    }

    /// Add execution parameter
    pub fn with_execution_param(mut self, key: String, value: f64) -> Self {
        if let Some(obj) = self.execution_params.as_object_mut() {
            obj.insert(key, serde_json::to_value(value).unwrap_or(Value::Null));
        } else {
            let mut map = serde_json::Map::new();
            map.insert(key, serde_json::to_value(value).unwrap_or(Value::Null));
            self.execution_params = Value::Object(map);
        }
        self
    }

    /// Set stop loss
    pub const fn with_stop_loss(mut self, stop_loss: Price) -> Self {
        self.stop_loss = Some(stop_loss);
        self
    }

    /// Set take profit
    pub const fn with_take_profit(mut self, take_profit: Price) -> Self {
        self.take_profit = Some(take_profit);
        self
    }

    /// Add metadata
    pub fn with_metadata(mut self, key: String, value: String) -> Self {
        if let Some(obj) = self.metadata.as_object_mut() {
            obj.insert(key, Value::String(value));
        } else {
            let mut map = serde_json::Map::new();
            map.insert(key, Value::String(value));
            self.metadata = Value::Object(map);
        }
        self
    }

    /// Update order status and timestamp
    pub fn update_status(&mut self, status: OrderStatus) {
        self.status = status;
        self.updated_at = Some(HftTimestamp::now_or_zero());
    }

    /// Fill order with given quantity and price
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::float_arithmetic)]
    pub fn fill(
        &mut self,
        fill_quantity: Quantity,
        fill_price: Price,
    ) -> Result<(), CommonTypeError> {
        // Use Add trait instead of checked_add (Quantity doesn't have checked_add method)
        let new_filled_value = self.filled_quantity.to_f64() + fill_quantity.to_f64();
        if !new_filled_value.is_finite() || new_filled_value < 0.0 {
            return Err(CommonTypeError::ValidationError {
                field: "fill_quantity".to_owned(),
                reason: "Fill quantity overflow".to_owned(),
            });
        }
        let new_filled =
            Quantity::from_f64(new_filled_value).map_err(|e| CommonTypeError::ValidationError {
                field: "fill_quantity".to_owned(),
                reason: format!("Fill quantity overflow: {}", e),
            })?;
        if new_filled > self.quantity {
            return Err(CommonTypeError::ValidationError {
                field: "fill_quantity".to_owned(),
                reason: "Fill quantity exceeds remaining quantity".to_owned(),
            });
        }

        // Update filled quantity
        let previous_filled = self.filled_quantity;
        let new_filled_value = self
            .filled_quantity
            .value
            .checked_add(fill_quantity.value)
            .ok_or_else(|| CommonTypeError::ValidationError {
                field: "filled_quantity".to_owned(),
                reason: "Filled quantity overflow".to_owned(),
            })?;
        self.filled_quantity = Quantity {
            value: new_filled_value,
        };

        let new_remaining_value = self
            .quantity
            .value
            .checked_sub(self.filled_quantity.value)
            .ok_or_else(|| CommonTypeError::ValidationError {
                field: "remaining_quantity".to_owned(),
                reason: "Remaining quantity underflow".to_owned(),
            })?;
        self.remaining_quantity = Quantity {
            value: new_remaining_value,
        };

        // Update average price
        if let Some(avg_price) = self.average_price {
            let total_value = avg_price.to_f64() * previous_filled.to_f64()
                + fill_price.to_f64() * fill_quantity.to_f64();
            let new_avg = Some(
                Price::from_f64(total_value / self.filled_quantity.to_f64()).unwrap_or(fill_price),
            );
            self.average_price = new_avg;
            self.avg_fill_price = new_avg; // Keep in sync
        } else {
            self.average_price = Some(fill_price);
            self.avg_fill_price = Some(fill_price); // Keep in sync
        }

        // Update status
        if self.is_filled() {
            self.update_status(OrderStatus::Filled);
        } else {
            self.update_status(OrderStatus::PartiallyFilled);
        }

        Ok(())
    }

    /// Create a limit order - convenience constructor
    pub fn limit(symbol: Symbol, side: OrderSide, quantity: Quantity, price: Price) -> Self {
        Self::new(symbol, side, quantity, Some(price), OrderType::Limit)
    }

    /// Create a market order - convenience constructor
    pub fn market(symbol: Symbol, side: OrderSide, quantity: Quantity) -> Self {
        Self::new(symbol, side, quantity, None, OrderType::Market)
    }

    /// Get symbol hash for performance-critical operations
    pub fn symbol_hash(&self) -> i64 {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};

        let mut hasher = DefaultHasher::new();
        self.symbol.as_str().hash(&mut hasher);
        i64::try_from(hasher.finish()).unwrap_or(0)
    }

    /// Get order timestamp
    pub const fn timestamp(&self) -> HftTimestamp {
        self.created_at
    }
}

impl Default for Order {
    fn default() -> Self {
        Self {
            id: OrderId::new(),
            client_order_id: None,
            broker_order_id: None,
            account_id: None,

            symbol: Symbol::from("DEFAULT"),
            side: OrderSide::Buy,
            order_type: OrderType::Market,
            status: OrderStatus::Created,
            time_in_force: TimeInForce::Day,

            quantity: Quantity::ONE,
            price: None,
            stop_price: None,
            filled_quantity: Quantity::ZERO,
            remaining_quantity: Quantity::ONE,
            average_price: None,
            avg_fill_price: None,
            average_fill_price: None,
            exchange_order_id: None,

            parent_id: None,
            execution_algorithm: None,
            execution_params: serde_json::json!({}),

            stop_loss: None,
            take_profit: None,

            created_at: HftTimestamp::now().unwrap_or(HftTimestamp { nanos: 0 }),
            updated_at: None,
            expires_at: None,

            metadata: serde_json::json!({}),
        }
    }
}

/// Represents a trading position - CANONICAL DEFINITION
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::FromRow))]
pub struct Position {
    /// Unique position identifier
    pub id: Uuid,

    /// Trading symbol
    pub symbol: String,

    /// Position quantity (positive for long, negative for short)
    pub quantity: Decimal,

    /// Average entry price
    pub avg_price: Decimal,

    /// Average cost per share
    pub avg_cost: Decimal,

    /// Cost basis for tax calculations
    pub basis: Decimal,

    /// Average entry price
    pub average_price: Decimal,

    /// Market value of position
    pub market_value: Decimal,

    /// Unrealized P&L
    pub unrealized_pnl: Decimal,

    /// Realized P&L
    pub realized_pnl: Decimal,

    /// Position creation timestamp
    pub created_at: DateTime<Utc>,

    /// Last update timestamp
    pub updated_at: DateTime<Utc>,

    /// Last updated timestamp
    pub last_updated: DateTime<Utc>,

    /// Current market price (for P&L calculation)
    pub current_price: Option<Decimal>,

    /// Position size in base currency
    pub notional_value: Decimal,

    /// Margin requirement
    pub margin_requirement: Decimal,
}

impl Position {
    /// Create a new position
    pub fn new(symbol: String, quantity: Decimal, avg_price: Decimal) -> Self {
        let now = Utc::now();
        let notional_value = quantity
            .abs()
            .checked_mul(avg_price)
            .unwrap_or(Decimal::ZERO);

        Self {
            id: Uuid::new_v4(),
            symbol,
            quantity,
            avg_price,
            avg_cost: avg_price, // Keep avg_cost synchronized with avg_price
            basis: quantity.checked_mul(avg_price).unwrap_or(Decimal::ZERO), // Cost basis calculation
            average_price: avg_price, // Same as avg_price for compatibility
            market_value: notional_value, // Initialize market value to notional value
            unrealized_pnl: Decimal::ZERO,
            realized_pnl: Decimal::ZERO,
            created_at: now,
            updated_at: now,
            last_updated: now, // Same as updated_at for compatibility
            current_price: None,
            notional_value,
            margin_requirement: notional_value
                .checked_mul(Decimal::from_str_exact("0.02").unwrap_or(Decimal::ZERO))
                .unwrap_or(Decimal::ZERO), // 2% margin
        }
    }

    /// Check if position is long
    pub fn is_long(&self) -> bool {
        self.quantity > Decimal::ZERO
    }

    /// Check if position is short
    pub fn is_short(&self) -> bool {
        self.quantity < Decimal::ZERO
    }

    /// Calculate unrealized P&L based on current price
    pub fn calculate_unrealized_pnl(&mut self, current_price: Decimal) {
        self.current_price = Some(current_price);
        self.market_value = self
            .quantity
            .abs()
            .checked_mul(current_price)
            .unwrap_or(Decimal::ZERO);
        // For both long and short: quantity * (current_price - avg_price)
        let price_diff = current_price
            .checked_sub(self.avg_price)
            .unwrap_or(Decimal::ZERO);
        self.unrealized_pnl = self
            .quantity
            .checked_mul(price_diff)
            .unwrap_or(Decimal::ZERO);
        let now = Utc::now();
        self.updated_at = now;
        self.last_updated = now; // Keep alias synchronized
    }

    /// Get total P&L (realized + unrealized)
    pub fn total_pnl(&self) -> Decimal {
        self.realized_pnl
            .checked_add(self.unrealized_pnl)
            .unwrap_or(Decimal::ZERO)
    }

    /// Calculate return on investment percentage
    pub fn roi_percentage(&self) -> Decimal {
        if self.notional_value.is_zero() {
            Decimal::ZERO
        } else {
            let pnl_ratio = self
                .total_pnl()
                .checked_div(self.notional_value)
                .unwrap_or(Decimal::ZERO);
            pnl_ratio
                .checked_mul(Decimal::from(100))
                .unwrap_or(Decimal::ZERO)
        }
    }
}

/// Represents a trade execution - CANONICAL DEFINITION
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::FromRow))]
pub struct Execution {
    /// Unique execution identifier
    pub id: Uuid,

    /// Related order ID
    pub order_id: Uuid,

    /// Trading symbol
    pub symbol: String,

    /// Executed quantity
    pub quantity: Decimal,

    /// Execution price
    pub price: Decimal,

    /// Execution side
    pub side: OrderSide,

    /// Trading fees
    pub fees: Decimal,

    /// Fee currency
    pub fee_currency: String,

    /// Execution timestamp
    pub executed_at: DateTime<Utc>,

    /// Execution timestamp
    pub timestamp: DateTime<Utc>,

    /// Symbol hash for performance
    pub symbol_hash: i64,

    /// Broker execution ID
    pub broker_execution_id: Option<String>,

    /// Counterparty information
    pub counterparty: Option<String>,

    /// Trade venue
    pub venue: Option<String>,

    /// Gross trade value
    pub gross_value: Decimal,

    /// Net trade value (after fees)
    pub net_value: Decimal,
}

impl Execution {
    /// Create a new execution
    pub fn new(
        order_id: Uuid,
        symbol: String,
        quantity: Decimal,
        price: Decimal,
        side: OrderSide,
        fees: Decimal,
    ) -> Self {
        let gross_value = quantity.checked_mul(price).unwrap_or(Decimal::ZERO);
        let net_value = if side == OrderSide::Buy {
            gross_value.checked_add(fees).unwrap_or(gross_value)
        } else {
            gross_value.checked_sub(fees).unwrap_or(gross_value)
        };
        let now = Utc::now();
        let symbol_hash = Self::hash_symbol(&symbol);

        Self {
            id: Uuid::new_v4(),
            order_id,
            symbol,
            quantity,
            price,
            side,
            fees,
            fee_currency: "USD".to_owned(), // Default to USD
            executed_at: now,
            timestamp: now, // Same as executed_at for compatibility
            symbol_hash,
            broker_execution_id: None,
            counterparty: None,
            venue: None,
            gross_value,
            net_value,
        }
    }

    /// Calculate effective price including fees
    pub fn effective_price(&self) -> Decimal {
        if self.quantity.is_zero() {
            self.price
        } else {
            self.net_value
                .checked_div(self.quantity)
                .unwrap_or(self.price)
        }
    }

    /// Hash symbol for performance
    fn hash_symbol(symbol: &str) -> i64 {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};

        let mut hasher = DefaultHasher::new();
        symbol.hash(&mut hasher);
        i64::try_from(hasher.finish()).unwrap_or(0)
    }
}

/// Core Price type using fixed-point arithmetic for precision
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Price {
    value: u64,
}

impl Price {
    /// Zero price constant
    pub const ZERO: Self = Self { value: 0 };
    /// One unit price constant (1.0)
    pub const ONE: Self = Self { value: 100_000_000 };
    /// One cent constant (0.01)
    pub const CENT: Self = Self { value: 1_000_000 };
    /// Maximum price value
    pub const MAX: Self = Self { value: u64::MAX };

    /// Create a Price from a floating-point value
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::as_conversions)]
    #[allow(clippy::float_arithmetic)]
    pub fn from_f64(value: f64) -> Result<Self, CommonTypeError> {
        if value < 0.0_f64 || !value.is_finite() {
            return Err(CommonTypeError::InvalidPrice {
                value: value.to_string(),
                reason: "Price validation failed".to_owned(),
            });
        }
        Ok(Self {
            #[allow(clippy::as_conversions)]
            #[allow(clippy::float_arithmetic)]
            value: (value * 100_000_000.0).round() as u64,
        })
    }

    /// Convert to floating-point representation
    #[must_use]
    #[allow(clippy::float_arithmetic)]
    /// Convert the quantity to a floating point value
    #[allow(clippy::as_conversions)]
    pub fn to_f64(&self) -> f64 {
        #[allow(clippy::as_conversions)]
        {
            self.value as f64 / 100_000_000.0
        }
    }

    /// Get floating-point representation (alias for `to_f64`)
    ///
    /// Convert quantity to f64 representation
    ///
    /// Convert quantity to f64 representation
    ///
    /// Convert quantity to f64 representation
    #[must_use]
    pub fn as_f64(&self) -> f64 {
        self.to_f64()
    }

    /// Create a zero price
    ///
    /// Create a zero quantity
    ///
    /// Create zero quantity
    #[must_use]
    pub const fn zero() -> Self {
        Self::ZERO
    }

    /// Convert to Decimal type for precise calculations
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn to_decimal(&self) -> Result<Decimal, CommonTypeError> {
        <Decimal as DecimalExt>::from_f64(self.to_f64()).ok_or_else(|| {
            CommonTypeError::InvalidPrice {
                value: "0.0".to_owned(),
                reason: "Price to Decimal conversion failed".to_owned(),
            }
        })
    }

    /// Create a Price from a Decimal value
    #[must_use]
    pub fn from_decimal(decimal: Decimal) -> Self {
        Self::from(decimal)
    }

    /// Create a new Price (alias for `from_f64`)
    ///
    /// Create a new quantity from a floating point value
    ///
    /// Create new quantity from f64 value
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn new(value: f64) -> Result<Self, CommonTypeError> {
        Self::from_f64(value)
    }

    /// Get the raw internal value representation
    ///
    /// Get the raw internal value
    ///
    /// Get the raw internal value representation
    #[must_use]
    pub const fn raw_value(&self) -> u64 {
        self.value
    }

    /// Get the price as a u64 value (same as `raw_value`)
    ///
    /// Convert to u64 representation
    ///
    /// Convert quantity to u64 representation
    #[must_use]
    pub const fn as_u64(&self) -> u64 {
        self.value
    }

    /// Create a Price from a raw u64 value
    ///
    /// Create a quantity from raw internal value
    ///
    /// Create quantity from raw u64 value
    #[must_use]
    pub const fn from_raw(value: u64) -> Self {
        Self { value }
    }

    /// Convert price to cents (divides by 1M for 8 decimal places)
    #[must_use]
    #[allow(clippy::integer_division)]
    pub const fn to_cents(&self) -> u64 {
        self.value / 1_000_000
    }

    /// Create a Price from cents value
    #[must_use]
    pub const fn from_cents(cents: u64) -> Self {
        Self {
            value: cents.saturating_mul(1_000_000),
        }
    }

    /// Check if the price is zero
    ///
    /// Check if the quantity is zero
    ///
    /// Check if quantity is zero
    #[must_use]
    pub const fn is_zero(&self) -> bool {
        self.value == 0
    }

    /// Check if the price is non-zero (has some value)
    ///
    /// Check if the quantity is non-zero (has some value)
    ///
    /// Check if quantity has a non-zero value
    #[must_use]
    pub const fn is_some(&self) -> bool {
        !self.is_zero()
    }

    /// Check if the price is zero (has no value)
    ///
    /// Check if the quantity is zero (has no value)
    ///
    /// Check if quantity is zero (none)
    #[must_use]
    pub const fn is_none(&self) -> bool {
        self.is_zero()
    }

    /// Get a reference to this price
    ///
    /// Get a reference to self
    ///
    /// Get a reference to self
    #[must_use]
    pub const fn as_ref(&self) -> &Self {
        self
    }

    /// Get the absolute value of the price (prices are always positive)
    ///
    /// Get the absolute value (quantities are always positive)
    ///
    /// Get absolute value (always positive for Quantity)
    #[must_use]
    pub const fn abs(&self) -> Self {
        *self
    }

    /// Multiply this price by another price
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::arithmetic_side_effects)]
    pub fn multiply(&self, other: Self) -> Result<Self, CommonTypeError> {
        #[allow(clippy::arithmetic_side_effects)]
        let result = *self * other;
        result
    }

    /// Subtract another price from this price
    ///
    /// Subtract another quantity from this quantity
    ///
    /// Subtract another quantity from this quantity
    ///
    /// Subtract another quantity from this quantity
    ///
    /// Subtract another quantity from this quantity
    #[must_use]
    #[allow(clippy::arithmetic_side_effects)]
    pub fn subtract(&self, other: Self) -> Self {
        *self - other
    }

    /// Divide this price by a floating point divisor
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn divide(&self, divisor: f64) -> Result<Self, CommonTypeError> {
        if divisor == 0.0 {
            return Err(CommonTypeError::InvalidPrice {
                value: format!("{:?}", self),
                reason: "Division by zero".to_owned(),
            });
        }
        #[allow(clippy::cast_precision_loss)]
        #[allow(clippy::arithmetic_side_effects)]
        let result = (self.value as f64 / divisor) as u64;
        Ok(Self { value: result })
    }
}

impl fmt::Display for Price {
    /// Format the price for display with 8 decimal places
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:.8}", self.to_f64())
    }
}

impl Default for Price {
    /// Returns the default price (zero)
    fn default() -> Self {
        Self::ZERO
    }
}

impl FromStr for Price {
    type Err = CommonTypeError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let parsed_value = s
            .parse::<f64>()
            .map_err(|e| CommonTypeError::InvalidPrice {
                value: s.to_owned(),
                reason: format!("Cannot parse '{}' as price: {}", s, e),
            })?;
        Self::from_f64(parsed_value)
    }
}

impl Add for Price {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        Self {
            value: self.value.saturating_add(rhs.value),
        }
    }
}

impl Sub for Price {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            value: self.value.saturating_sub(rhs.value),
        }
    }
}

impl Mul<f64> for Price {
    #[allow(clippy::float_arithmetic)]
    type Output = Result<Self, CommonTypeError>;
    fn mul(self, rhs: f64) -> Self::Output {
        Self::from_f64(self.to_f64() * rhs)
    }
}

#[allow(clippy::float_arithmetic)]
impl Div<f64> for Price {
    type Output = Result<Self, CommonTypeError>;
    fn div(self, rhs: f64) -> Self::Output {
        if rhs == 0.0_f64 {
            return Err(CommonTypeError::ConversionError {
                message: "Cannot divide price by zero".to_owned(),
            });
        }
        Self::from_f64(self.to_f64() / rhs)
    }
}

impl From<Decimal> for Price {
    fn from(decimal: Decimal) -> Self {
        let f64_val: f64 = TryInto::<f64>::try_into(decimal).unwrap_or_else(|_| {
            tracing::warn!("Failed to convert Decimal to f64, using 0.0 as fallback");
            0.0_f64
        });
        Self::from_f64(f64_val).unwrap_or_else(|_| {
            tracing::warn!(
                "Failed to create Price from f64 value {}, using ZERO",
                f64_val
            );
            Self::ZERO
        })
    }
}

impl From<Price> for Decimal {
    fn from(price: Price) -> Self {
        price.to_decimal().unwrap_or(Decimal::ZERO)
    }
}

// TryFrom<Quantity> for Decimal removed due to conflicting blanket implementation
// Use qty.to_decimal() directly instead
impl From<Quantity> for Decimal {
    fn from(qty: Quantity) -> Self {
        qty.to_decimal().unwrap_or(Decimal::ZERO)
    }
}

// TryFrom<Quantity> for Decimal removed due to conflict with From implementation
// Use the From implementation instead which handles errors by returning ZERO

// =============================================================================
// Decimal Extension Trait
// =============================================================================

impl Mul<Self> for Price {
    #[allow(clippy::float_arithmetic)]
    #[allow(clippy::arithmetic_side_effects)]
    type Output = Result<Self, CommonTypeError>;
    fn mul(self, rhs: Self) -> Self::Output {
        Self::from_f64(self.to_f64() * rhs.to_f64())
    }
}

impl TryFrom<String> for Price {
    type Error = CommonTypeError;
    fn try_from(s: String) -> Result<Self, Self::Error> {
        Self::from_str(&s)
    }
}

impl TryFrom<&str> for Price {
    type Error = CommonTypeError;
    fn try_from(s: &str) -> Result<Self, Self::Error> {
        Self::from_str(s)
    }
}

impl PartialEq<f64> for Price {
    #[allow(clippy::float_arithmetic)]
    fn eq(&self, other: &f64) -> bool {
        (self.to_f64() - other).abs() < f64::EPSILON
    }
}

impl PartialEq<Price> for f64 {
    #[allow(clippy::float_arithmetic)]
    fn eq(&self, other: &Price) -> bool {
        (self - other.to_f64()).abs() < f64::EPSILON
    }
}

impl AddAssign for Price {
    fn add_assign(&mut self, rhs: Self) {
        self.value = self.value.saturating_add(rhs.value);
    }
}

impl SubAssign for Price {
    fn sub_assign(&mut self, rhs: Self) {
        self.value = self.value.saturating_sub(rhs.value);
    }
}

impl MulAssign<f64> for Price {
    fn mul_assign(&mut self, rhs: f64) {
        if let Ok(result) = self.mul(rhs) {
            *self = result;
        }
        // If multiplication fails, self remains unchanged
    }
}

impl DivAssign<f64> for Price {
    fn div_assign(&mut self, rhs: f64) {
        if let Ok(result) = self.div(rhs) {
            *self = result;
        }
        // If division fails, self remains unchanged
    }
}

impl PartialOrd<f64> for Price {
    fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
        self.to_f64().partial_cmp(other)
    }
}

impl PartialOrd<Price> for f64 {
    fn partial_cmp(&self, other: &Price) -> Option<std::cmp::Ordering> {
        self.partial_cmp(&other.to_f64())
    }
}

/// Core Quantity type using fixed-point arithmetic
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Quantity {
    pub(crate) value: u64,
}

impl Quantity {
    /// Zero quantity constant
    pub const ZERO: Self = Self { value: 0 };
    /// One unit quantity constant
    pub const ONE: Self = Self { value: 100_000_000 };
    /// Maximum possible quantity
    pub const MAX: Self = Self { value: u64::MAX };

    /// Create a Quantity from a floating point value
    #[allow(clippy::as_conversions)]
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::float_arithmetic)]
    pub fn from_f64(value: f64) -> Result<Self, CommonTypeError> {
        if value < 0.0_f64 || !value.is_finite() {
            return Err(CommonTypeError::InvalidQuantity {
                value: value.to_string(),
                reason: "Quantity validation failed".to_owned(),
            });
        }
        Ok(Self {
            value: (value * 100_000_000.0).round() as u64,
        })
    }

    /// Convert quantity to floating point representation
    #[must_use]
    #[allow(clippy::as_conversions)]
    #[allow(clippy::float_arithmetic)]
    pub fn to_f64(&self) -> f64 {
        self.value as f64 / 100_000_000.0
    }

    /// Convert the quantity to a Decimal value
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn to_decimal(&self) -> Result<Decimal, CommonTypeError> {
        Decimal::from_f64_retain(self.to_f64()).ok_or_else(|| CommonTypeError::InvalidQuantity {
            value: "0.0".to_owned(),
            reason: "Quantity to Decimal conversion failed".to_owned(),
        })
    }

    /// Get the internal value representation
    #[must_use]
    pub const fn value(&self) -> u64 {
        self.value
    }

    /// Get the raw internal value representation
    #[must_use]
    pub const fn raw_value(&self) -> u64 {
        self.value
    }

    /// Convert quantity to u64 representation
    #[must_use]
    pub const fn as_u64(&self) -> u64 {
        self.value
    }

    /// Create quantity from raw u64 value
    #[must_use]
    pub const fn from_raw(value: u64) -> Self {
        Self { value }
    }

    /// Create new quantity from f64 value
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::as_conversions)]
    pub fn new(value: f64) -> Result<Self, CommonTypeError> {
        Self::from_f64(value)
    }

    /// Create zero quantity
    #[must_use]
    pub const fn zero() -> Self {
        #[allow(clippy::as_conversions)]
        Self::ZERO
    }

    /// Create a quantity from an i64 value
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::as_conversions)]
    pub fn from_i64(value: i64) -> Result<Self, CommonTypeError> {
        Self::from_f64(value as f64)
    }

    /// Create a quantity from a u64 value
    ///
    /// # Errors
    #[allow(clippy::as_conversions)]
    /// Returns error if the operation fails
    pub fn from_u64(value: u64) -> Result<Self, CommonTypeError> {
        Self::from_f64(value as f64)
    }

    /// Create a quantity from a Decimal value
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn from_decimal(decimal: Decimal) -> Result<Self, CommonTypeError> {
        use std::convert::TryFrom;
        Self::try_from(decimal).map_err(|e| CommonTypeError::InvalidQuantity {
            value: decimal.to_string(),
            reason: format!("Failed to convert Decimal to Quantity: {}", e),
        })
    }

    /// Check if quantity is zero
    #[must_use]
    pub const fn is_zero(&self) -> bool {
        self.value == 0
    }

    /// Check if quantity has a non-zero value
    #[must_use]
    pub const fn is_some(&self) -> bool {
        !self.is_zero()
    }

    /// Check if quantity is zero (none)
    #[must_use]
    pub const fn is_none(&self) -> bool {
        self.is_zero()
    }

    /// Get a reference to self
    #[must_use]
    pub const fn as_ref(&self) -> &Self {
        self
    }

    /// Get absolute value (always positive for Quantity)
    #[must_use]
    pub const fn abs(&self) -> Self {
        *self
    }

    /// Get the sign of the quantity (1.0 for positive, 0.0 for zero)
    #[must_use]
    pub const fn signum(&self) -> f64 {
        if self.value > 0 {
            1.0
        } else {
            0.0
        }
    }

    /// Check if quantity is positive
    #[must_use]
    pub const fn is_positive(&self) -> bool {
        self.value > 0
    }

    /// Check if quantity is negative (always false for Quantity)
    #[must_use]
    pub const fn is_negative(&self) -> bool {
        false
    }

    /// Convert quantity to f64 representation
    #[must_use]
    pub fn as_f64(&self) -> f64 {
        self.to_f64()
    }

    /// Create quantity from number of shares
    #[must_use]
    pub const fn from_shares(shares: u64) -> Self {
        Self {
            value: shares.saturating_mul(100_000_000),
        }
    }

    /// Convert quantity to number of shares
    #[must_use]
    #[allow(clippy::integer_division)]
    pub const fn to_shares(&self) -> u64 {
        self.value / 100_000_000
    }

    /// Multiply this quantity by another quantity
    ///
    /// # Errors
    /// Returns error if the operation fails
    #[allow(clippy::float_arithmetic)]
    #[allow(clippy::arithmetic_side_effects)]
    pub fn multiply(&self, other: Self) -> Result<Self, CommonTypeError> {
        Self::from_f64(self.to_f64() * other.to_f64())
    }

    /// Subtract another quantity from this quantity
    #[must_use]
    pub fn subtract(&self, other: Self) -> Self {
        Self {
            value: self.value.checked_sub(other.value).unwrap_or_else(|| {
                tracing::warn!(
                    "Quantity subtraction underflow: {} - {}, returning 0",
                    self.value,
                    other.value
                );
                0
            }),
        }
    }

    /// Checked addition with overflow protection
    #[must_use]
    pub const fn checked_add(&self, other: Self) -> Option<Self> {
        match self.value.checked_add(other.value) {
            Some(value) => Some(Self { value }),
            None => None,
        }
    }

    /// Checked subtraction with underflow protection
    #[must_use]
    pub const fn checked_sub(&self, other: Self) -> Option<Self> {
        match self.value.checked_sub(other.value) {
            Some(value) => Some(Self { value }),
            None => None,
        }
    }
}

impl Default for Quantity {
    fn default() -> Self {
        Self::ZERO
    }
}

impl FromStr for Quantity {
    type Err = CommonTypeError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let parsed_value = s
            .parse::<f64>()
            .map_err(|e| CommonTypeError::InvalidQuantity {
                value: s.to_owned(),
                reason: format!("Cannot parse '{}' as quantity: {}", s, e),
            })?;
        Self::from_f64(parsed_value)
    }
}

impl fmt::Display for Quantity {
    /// Format the quantity for display with 8 decimal places
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:.8}", self.to_f64())
    }
}

impl TryFrom<i32> for Quantity {
    type Error = CommonTypeError;
    fn try_from(value: i32) -> Result<Self, Self::Error> {
        Self::new(f64::from(value))
    }
}

impl TryFrom<u64> for Quantity {
    type Error = CommonTypeError;
    fn try_from(value: u64) -> Result<Self, Self::Error> {
        #[allow(clippy::as_conversions)]
        let f64_value = value as f64;
        Self::new(f64_value)
    }
}

impl TryFrom<f64> for Quantity {
    type Error = CommonTypeError;
    fn try_from(value: f64) -> Result<Self, Self::Error> {
        Self::new(value)
    }
}

impl TryFrom<Decimal> for Quantity {
    type Error = CommonTypeError;
    fn try_from(decimal: Decimal) -> Result<Self, Self::Error> {
        let f64_val: f64 =
            TryInto::<f64>::try_into(decimal).map_err(|e| CommonTypeError::ConversionError {
                message: format!("Failed to convert Decimal to f64: {}", e),
            })?;
        Self::from_f64(f64_val)
    }
}

impl TryFrom<String> for Quantity {
    type Error = CommonTypeError;
    fn try_from(s: String) -> Result<Self, Self::Error> {
        Self::from_str(&s)
    }
}

impl TryFrom<&str> for Quantity {
    type Error = CommonTypeError;
    fn try_from(s: &str) -> Result<Self, Self::Error> {
        Self::from_str(s)
    }
}

impl PartialEq<f64> for Quantity {
    #[allow(clippy::float_arithmetic)]
    fn eq(&self, other: &f64) -> bool {
        (self.to_f64() - other).abs() < f64::EPSILON
    }
}

impl PartialEq<Quantity> for f64 {
    #[allow(clippy::float_arithmetic)]
    fn eq(&self, other: &Quantity) -> bool {
        (self - other.to_f64()).abs() < f64::EPSILON
    }
}

impl PartialOrd<f64> for Quantity {
    fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
        self.to_f64().partial_cmp(other)
    }
}

impl PartialOrd<Quantity> for f64 {
    fn partial_cmp(&self, other: &Quantity) -> Option<std::cmp::Ordering> {
        self.partial_cmp(&other.to_f64())
    }
}

impl Add for Quantity {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        Self {
            value: self.value.saturating_add(rhs.value),
        }
    }
}

impl Sub for Quantity {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            value: self.value.saturating_sub(rhs.value),
        }
    }
}

impl Mul<f64> for Quantity {
    #[allow(clippy::float_arithmetic)]
    type Output = Result<Self, CommonTypeError>;
    fn mul(self, rhs: f64) -> Self::Output {
        Self::from_f64(self.to_f64() * rhs)
    }
}

impl Div<f64> for Quantity {
    #[allow(clippy::float_arithmetic)]
    type Output = Result<Self, CommonTypeError>;
    fn div(self, rhs: f64) -> Self::Output {
        if rhs == 0.0_f64 {
            return Err(CommonTypeError::ConversionError {
                message: "Cannot divide quantity by zero".to_owned(),
            });
        }
        Self::from_f64(self.to_f64() / rhs)
    }
}

impl Sum for Quantity {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::ZERO, |acc, x| Self {
            value: acc.value.saturating_add(x.value),
        })
    }
}

impl<'quantity> Sum<&'quantity Self> for Quantity {
    fn sum<I: Iterator<Item = &'quantity Self>>(iter: I) -> Self {
        iter.fold(Self::ZERO, |acc, x| Self {
            value: acc.value.saturating_add(x.value),
        })
    }
}

// =============================================================================
// SQLX IMPLEMENTATIONS FOR FINANCIAL TYPES
// =============================================================================

#[cfg(feature = "database")]
mod sqlx_impls {
    use super::{HftTimestamp, Price, Quantity};
    use crate::types::{MarketRegime, OrderId, OrderSide, OrderStatus, OrderType};
    use rust_decimal::Decimal as RustDecimal;
    use sqlx::{
        decode::Decode,
        encode::{Encode, IsNull},
        error::BoxDynError,
        postgres::{PgArgumentBuffer, PgTypeInfo, PgValueRef, Postgres},
        Type,
    };

    // SQLx implementations for Price
    impl Type<Postgres> for Price {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("NUMERIC")
        }
    }

    impl<'query> Encode<'query, Postgres> for Price {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            // Convert our fixed-point u64 to rust_decimal::Decimal with 8 decimal places
            let decimal_value = RustDecimal::new(i64::try_from(self.raw_value()).unwrap_or(0), 8);
            decimal_value.encode_by_ref(buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for Price {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            // Decode from NUMERIC to rust_decimal::Decimal
            let decimal_value = <RustDecimal as Decode<Postgres>>::decode(value)?;

            // Validate scale matches our fixed-point precision (8 decimal places)
            if decimal_value.scale() != 8 {
                return Err(format!(
                    "Invalid scale for Price: expected 8, got {}",
                    decimal_value.scale()
                )
                .into());
            }

            // Extract mantissa and convert to our u64 representation
            let mantissa = decimal_value.mantissa();
            let inner_val = u64::try_from(mantissa).map_err(|e| {
                format!(
                    "Failed to convert negative or overflowing NUMERIC to Price: {}",
                    e
                )
            })?;

            Ok(Price::from_raw(inner_val))
        }
    }
    // SQLx implementations for Quantity
    impl Type<Postgres> for Quantity {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("NUMERIC")
        }
    }

    impl<'query> Encode<'query, Postgres> for Quantity {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            // Convert our fixed-point u64 to rust_decimal::Decimal with 8 decimal places
            let decimal_value = RustDecimal::new(i64::try_from(self.raw_value()).unwrap_or(0), 8);
            decimal_value.encode_by_ref(buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for Quantity {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            // Decode from NUMERIC to rust_decimal::Decimal
            let decimal_value = <RustDecimal as Decode<Postgres>>::decode(value)?;

            // Validate scale matches our fixed-point precision (8 decimal places)
            if decimal_value.scale() != 8 {
                return Err(format!(
                    "Invalid scale for Quantity: expected 8, got {}",
                    decimal_value.scale()
                )
                .into());
            }

            // Extract mantissa and convert to our u64 representation
            let mantissa = decimal_value.mantissa();
            let inner_val = u64::try_from(mantissa).map_err(|e| {
                format!(
                    "Failed to convert negative or overflowing NUMERIC to Quantity: {}",
                    e
                )
            })?;

            Ok(Quantity::from_raw(inner_val))
        }
    }

    // SQLx implementations for TimeInForce
    impl Type<Postgres> for crate::types::TimeInForce {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("TEXT")
        }
    }

    impl<'query> Encode<'query, Postgres> for crate::types::TimeInForce {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            // Use the Display trait to convert enum to string representation
            <&str as Encode<Postgres>>::encode(self.to_string().as_str(), buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for crate::types::TimeInForce {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            // Decode from TEXT to string, then parse to enum
            let s = <&str as Decode<Postgres>>::decode(value)?;
            match s {
                "DAY" => Ok(crate::types::TimeInForce::Day),
                "GTC" => Ok(crate::types::TimeInForce::GoodTillCancel),
                "IOC" => Ok(crate::types::TimeInForce::ImmediateOrCancel),
                "FOK" => Ok(crate::types::TimeInForce::FillOrKill),
                _ => Err(format!("Invalid TimeInForce value: {}", s).into()),
            }
        }
    }

    // SQLx implementations for OrderStatus
    impl Type<Postgres> for OrderStatus {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("TEXT")
        }
    }

    impl<'query> Encode<'query, Postgres> for OrderStatus {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            let value = match self {
                OrderStatus::Created => "CREATED",
                OrderStatus::Submitted => "SUBMITTED",
                OrderStatus::PartiallyFilled => "PARTIALLY_FILLED",
                OrderStatus::Filled => "FILLED",
                OrderStatus::Rejected => "REJECTED",
                OrderStatus::Cancelled => "CANCELLED",
                OrderStatus::New => "NEW",
                OrderStatus::Expired => "EXPIRED",
                OrderStatus::Pending => "PENDING",
                OrderStatus::Working => "WORKING",
                OrderStatus::Unknown => "UNKNOWN",
                OrderStatus::Suspended => "SUSPENDED",
                OrderStatus::PendingCancel => "PENDING_CANCEL",
                OrderStatus::PendingReplace => "PENDING_REPLACE",
            };
            <&str as Encode<Postgres>>::encode_by_ref(&value, buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for OrderStatus {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let s = <String as Decode<Postgres>>::decode(value)?;
            match s.as_str() {
                "CREATED" => Ok(OrderStatus::Created),
                "SUBMITTED" => Ok(OrderStatus::Submitted),
                "PARTIALLY_FILLED" => Ok(OrderStatus::PartiallyFilled),
                "FILLED" => Ok(OrderStatus::Filled),
                "REJECTED" => Ok(OrderStatus::Rejected),
                "CANCELLED" => Ok(OrderStatus::Cancelled),
                "NEW" => Ok(OrderStatus::New),
                "EXPIRED" => Ok(OrderStatus::Expired),
                "PENDING" => Ok(OrderStatus::Pending),
                "WORKING" => Ok(OrderStatus::Working),
                "UNKNOWN" => Ok(OrderStatus::Unknown),
                "SUSPENDED" => Ok(OrderStatus::Suspended),
                "PENDING_CANCEL" => Ok(OrderStatus::PendingCancel),
                "PENDING_REPLACE" => Ok(OrderStatus::PendingReplace),
                _ => Err(format!("Invalid OrderStatus value: {}", s).into()),
            }
        }
    }

    // SQLx implementations for OrderSide
    impl Type<Postgres> for OrderSide {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("TEXT")
        }
    }

    impl<'query> Encode<'query, Postgres> for OrderSide {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            let value = match self {
                OrderSide::Buy => "BUY",
                OrderSide::Sell => "SELL",
            };
            <&str as Encode<Postgres>>::encode_by_ref(&value, buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for OrderSide {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let s = <String as Decode<Postgres>>::decode(value)?;
            match s.as_str() {
                "BUY" => Ok(OrderSide::Buy),
                "SELL" => Ok(OrderSide::Sell),
                _ => Err(format!("Invalid OrderSide value: {}", s).into()),
            }
        }
    }

    // SQLx implementations for OrderType
    impl Type<Postgres> for OrderType {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("TEXT")
        }
    }

    impl<'query> Encode<'query, Postgres> for OrderType {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            let value = match self {
                OrderType::Market => "MARKET",
                OrderType::Limit => "LIMIT",
                OrderType::Stop => "STOP",
                OrderType::StopLimit => "STOP_LIMIT",
                OrderType::Iceberg => "ICEBERG",
                OrderType::TrailingStop => "TRAILING_STOP",
                OrderType::Hidden => "HIDDEN",
            };
            <&str as Encode<Postgres>>::encode_by_ref(&value, buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for OrderType {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let s = <String as Decode<Postgres>>::decode(value)?;
            match s.as_str() {
                "MARKET" => Ok(OrderType::Market),
                "LIMIT" => Ok(OrderType::Limit),
                "STOP" => Ok(OrderType::Stop),
                "STOP_LIMIT" => Ok(OrderType::StopLimit),
                "ICEBERG" => Ok(OrderType::Iceberg),
                "TRAILING_STOP" => Ok(OrderType::TrailingStop),
                "HIDDEN" => Ok(OrderType::Hidden),
                _ => Err(format!("Invalid OrderType value: {}", s).into()),
            }
        }
    }

    // SQLx implementations for MarketRegime
    impl Type<Postgres> for MarketRegime {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("TEXT")
        }
    }

    impl<'query> Encode<'query, Postgres> for MarketRegime {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            let value = match self {
                MarketRegime::Normal => "NORMAL",
                MarketRegime::Crisis => "CRISIS",
                MarketRegime::Trending => "TRENDING",
                MarketRegime::Sideways => "SIDEWAYS",
                MarketRegime::Bull => "BULL",
                MarketRegime::Bear => "BEAR",
                MarketRegime::HighVolatility => "HIGH_VOLATILITY",
                MarketRegime::LowVolatility => "LOW_VOLATILITY",
                MarketRegime::Volatile => "VOLATILE",
                MarketRegime::Calm => "CALM",
                MarketRegime::Unknown => "UNKNOWN",
                MarketRegime::Recovery => "RECOVERY",
                MarketRegime::Bubble => "BUBBLE",
                MarketRegime::Correction => "CORRECTION",
                MarketRegime::Custom(id) => {
                    return <String as Encode<Postgres>>::encode_by_ref(
                        &format!("CUSTOM_{}", id),
                        buf,
                    )
                },
            };
            <&str as Encode<Postgres>>::encode_by_ref(&value, buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for MarketRegime {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let s = <String as Decode<Postgres>>::decode(value)?;
            match s.as_str() {
                "NORMAL" => Ok(MarketRegime::Normal),
                "CRISIS" => Ok(MarketRegime::Crisis),
                "TRENDING" => Ok(MarketRegime::Trending),
                "SIDEWAYS" => Ok(MarketRegime::Sideways),
                "BULL" => Ok(MarketRegime::Bull),
                "BEAR" => Ok(MarketRegime::Bear),
                "HIGH_VOLATILITY" => Ok(MarketRegime::HighVolatility),
                "LOW_VOLATILITY" => Ok(MarketRegime::LowVolatility),
                "VOLATILE" => Ok(MarketRegime::Volatile),
                "CALM" => Ok(MarketRegime::Calm),
                "UNKNOWN" => Ok(MarketRegime::Unknown),
                "RECOVERY" => Ok(MarketRegime::Recovery),
                "BUBBLE" => Ok(MarketRegime::Bubble),
                "CORRECTION" => Ok(MarketRegime::Correction),
                _ => {
                    // Handle Custom(id) format
                    if let Some(id_str) = s.strip_prefix("CUSTOM_") {
                        if let Ok(id) = id_str.parse::<usize>() {
                            Ok(MarketRegime::Custom(id))
                        } else {
                            Err(format!("Invalid MarketRegime Custom ID: {}", id_str).into())
                        }
                    } else {
                        Err(format!("Invalid MarketRegime value: {}", s).into())
                    }
                },
            }
        }
    }

    // SQLx implementations for HftTimestamp
    // Maps to PostgreSQL BIGINT (stores nanoseconds since Unix epoch)
    // Note: Limited to i64::MAX nanoseconds (year 2262) due to PostgreSQL BIGINT constraints
    impl<'query> Encode<'query, Postgres> for HftTimestamp {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            // Cast u64 to i64 for PostgreSQL BIGINT compatibility
            <i64 as Encode<Postgres>>::encode(i64::try_from(self.nanos()).unwrap_or(0), buf)
        }
    }

    impl<'row> Decode<'row, Postgres> for HftTimestamp {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let val = <i64 as Decode<Postgres>>::decode(value)?;
            // Cast i64 back to u64 for internal representation
            Ok(HftTimestamp::from_nanos(u64::try_from(val).unwrap_or(0)))
        }
    }

    impl Type<Postgres> for HftTimestamp {
        fn type_info() -> <Postgres as sqlx::Database>::TypeInfo {
            <i64 as Type<Postgres>>::type_info()
        }

        fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
            <i64 as Type<Postgres>>::compatible(ty)
        }
    }

    // SQLx implementations for OrderId (uses BIGINT for u64)
    impl Type<Postgres> for OrderId {
        fn type_info() -> PgTypeInfo {
            PgTypeInfo::with_name("BIGINT")
        }
    }

    impl<'query> Encode<'query, Postgres> for OrderId {
        fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
            <i64 as Encode<Postgres>>::encode_by_ref(
                &(i64::try_from(self.value()).unwrap_or(0)),
                buf,
            )
        }
    }

    impl<'row> Decode<'row, Postgres> for OrderId {
        fn decode(value: PgValueRef<'row>) -> Result<Self, BoxDynError> {
            let id = <i64 as Decode<Postgres>>::decode(value)?;
            Ok(OrderId::from_u64(u64::try_from(id).unwrap_or(0)))
        }
    }
}

/// Volume type - alias for Quantity with the same fixed-point arithmetic
///
/// `SQLx` traits are automatically inherited from Quantity
pub type Volume = Quantity;

// ORDER TYPES ALREADY DEFINED ABOVE - No need to re-export from trading_engine
// =============================================================================
// CORE ID TYPES (MOVED FROM TRADING_ENGINE)
// =============================================================================

/// Order identifier with ultra-fast atomic generation
///
/// Replaces slow UUID generation (1ms+) with atomic increment (~5ns)
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct OrderId(u64);

impl Default for OrderId {
    fn default() -> Self {
        Self::new()
    }
}

impl OrderId {
    /// Generate next `OrderId` using atomic counter - <50ns performance
    pub fn new() -> Self {
        use std::sync::atomic::{AtomicU64, Ordering};
        static COUNTER: AtomicU64 = AtomicU64::new(1);
        Self(COUNTER.fetch_add(1, Ordering::Relaxed))
    }

    /// Create `OrderId` from u64 value
    #[must_use]
    pub const fn from_u64(value: u64) -> Self {
        Self(value)
    }

    /// Get u64 value
    #[must_use]
    pub const fn value(&self) -> u64 {
        self.0
    }

    /// Get u64 value for performance-critical code (alias for value)
    #[must_use]
    pub const fn as_u64(&self) -> u64 {
        self.0
    }

    /// Get as string for compatibility
    #[must_use]
    pub fn as_str(&self) -> String {
        self.0.to_string()
    }
}

impl fmt::Display for OrderId {
    /// Format the order ID for display
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl From<u64> for OrderId {
    /// Create an `OrderId` from a u64 value
    fn from(value: u64) -> Self {
        Self(value)
    }
}

impl From<OrderId> for u64 {
    /// Convert an `OrderId` to u64
    fn from(order_id: OrderId) -> Self {
        order_id.0
    }
}

impl FromStr for OrderId {
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse::<u64>().map(OrderId)
    }
}

impl From<String> for OrderId {
    /// Create an `OrderId` from a String, generating new ID if parsing fails
    fn from(s: String) -> Self {
        s.parse().unwrap_or_else(|_| Self::new())
    }
}

impl From<&str> for OrderId {
    /// Create an `OrderId` from a &str, generating new ID if parsing fails
    fn from(s: &str) -> Self {
        s.parse().unwrap_or_else(|_| Self::new())
    }
}

/// Execution identifier with validation
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::Type))]
pub struct ExecutionId(String);

impl ExecutionId {
    /// Create a new execution ID with validation
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn new<S: Into<String>>(id: S) -> Result<Self, CommonTypeError> {
        let id = id.into();
        if id.trim().is_empty() {
            return Err(CommonTypeError::ValidationError {
                field: "execution_id".to_owned(),
                reason: "Execution ID cannot be empty".to_owned(),
            });
        }
        Ok(Self(id))
    }

    /// Generate a new random execution ID
    pub fn generate() -> Self {
        Self(uuid::Uuid::new_v4().to_string())
    }

    /// Get execution ID as string slice
    pub fn as_str(&self) -> &str {
        &self.0
    }

    /// Convert execution ID into owned string
    pub fn into_string(self) -> String {
        self.0
    }
}

impl fmt::Display for ExecutionId {
    /// Format the execution ID for display
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl FromStr for ExecutionId {
    type Err = CommonTypeError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Self::new(s)
    }
}

/// Trade identifier with validation
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TradeId(String);

impl TradeId {
    /// Create a new trade ID with validation
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn new<S: Into<String>>(id: S) -> Result<Self, CommonTypeError> {
        let id = id.into();
        if id.is_empty() {
            return Err(CommonTypeError::ValidationError {
                field: "trade_id".to_owned(),
                reason: "Trade ID cannot be empty".to_owned(),
            });
        }
        Ok(Self(id))
    }

    /// Get the trade ID as a string slice
    pub fn as_str(&self) -> &str {
        &self.0
    }
    /// Convert the trade ID into an owned string
    pub fn into_string(self) -> String {
        self.0
    }
}

impl fmt::Display for TradeId {
    /// Format the trade ID for display
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// Trading symbol with validation
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "database", derive(sqlx::Type))]
pub struct Symbol {
    value: String,
}

impl Symbol {
    /// Create a new symbol from a string
    #[must_use]
    pub const fn new(s: String) -> Self {
        Self { value: s }
    }

    /// Create a new Symbol with validation
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn new_validated(s: String) -> Result<Self, CommonTypeError> {
        if s.trim().is_empty() {
            return Err(CommonTypeError::ValidationError {
                field: "symbol".to_owned(),
                reason: "Symbol cannot be empty".to_owned(),
            });
        }
        Ok(Self { value: s })
    }

    /// Create a Symbol from &str with validation
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn from_str_validated(s: &str) -> Result<Self, CommonTypeError> {
        Self::new_validated(s.to_owned())
    }

    /// Get the symbol as a string slice
    #[must_use]
    pub fn as_str(&self) -> &str {
        &self.value
    }
    /// Get the symbol value as a string slice
    #[must_use]
    pub fn value(&self) -> &str {
        &self.value
    }
    /// Get the symbol as bytes
    #[must_use]
    pub fn as_bytes(&self) -> &[u8] {
        self.value.as_bytes()
    }
    /// Check if the symbol is empty
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.value.is_empty()
    }
    /// Convert the symbol to uppercase
    #[must_use]
    pub fn to_uppercase(&self) -> String {
        self.value.to_uppercase()
    }
    /// Replace occurrences in the symbol
    #[must_use]
    pub fn replace(&self, from: &str, to: &str) -> String {
        self.value.replace(from, to)
    }

    /// Helper for risk management - creates a 'NONE' symbol
    #[must_use]
    pub fn none() -> Self {
        "NONE".parse().unwrap()
    }

    /// Check if the symbol contains a pattern
    #[must_use]
    pub fn contains(&self, pattern: &str) -> bool {
        self.value.contains(pattern)
    }
}

impl FromStr for Symbol {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Self {
            value: s.to_owned(),
        })
    }
}

// Additional implementation to support conversion from &Symbol to &str
impl AsRef<str> for Symbol {
    /// Convert symbol to string reference
    fn as_ref(&self) -> &str {
        &self.value
    }
}

impl fmt::Display for Symbol {
    /// Format the symbol for display
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.value)
    }
}

impl From<String> for Symbol {
    /// Create a Symbol from a String
    fn from(s: String) -> Self {
        Self::new(s)
    }
}
impl From<&str> for Symbol {
    /// Create a Symbol from a &str
    fn from(s: &str) -> Self {
        Self::new(s.to_owned())
    }
}

// TryFrom implementations removed due to conflicting blanket implementations
// Use Symbol::new_validated() or Symbol::from_validated() directly instead

impl Default for Symbol {
    /// Returns the default symbol (empty string)
    fn default() -> Self {
        Self::new(String::new())
    }
}

impl PartialEq<str> for Symbol {
    fn eq(&self, other: &str) -> bool {
        self.value == other
    }
}

impl PartialEq<&str> for Symbol {
    fn eq(&self, other: &&str) -> bool {
        self.value == *other
    }
}

impl PartialEq<String> for Symbol {
    fn eq(&self, other: &String) -> bool {
        &self.value == other
    }
}

impl PartialEq<Symbol> for &str {
    fn eq(&self, other: &Symbol) -> bool {
        *self == other.value
    }
}

impl PartialEq<Symbol> for String {
    fn eq(&self, other: &Symbol) -> bool {
        self == &other.value
    }
}

// TimeInForce moved to canonical source: common::types::TimeInForce

// Currency moved to canonical source: common::types::Currency

// Price moved to canonical source: common::types::Price

// Quantity moved to canonical source: common::types::Quantity
// Volume moved to canonical source: common::types::Quantity (as Volume alias)

/// Money amount with currency
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Money {
    /// The monetary amount
    pub amount: Decimal,
    /// The currency of the amount
    pub currency: Currency,
}

impl Money {
    /// Create new money amount
    pub const fn new(amount: Decimal, currency: Currency) -> Self {
        Self { amount, currency }
    }
}

impl fmt::Display for Money {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{} {}", self.amount, self.currency)
    }
}

// OrderId moved to canonical source: common::types::OrderId

// TradeId moved to canonical source: common::types::TradeId

// Symbol moved to canonical source: common::types::Symbol

/// Type-safe account identifier
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AccountId(String);

impl AccountId {
    /// Create a new account ID with validation
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn new<S: Into<String>>(id: S) -> Result<Self, CommonTypeError> {
        let id = id.into();
        if id.trim().is_empty() {
            return Err(CommonTypeError::InvalidIdentifier {
                field: "account_id".to_owned(),
                reason: "Account ID cannot be empty".to_owned(),
            });
        }
        Ok(Self(id))
    }

    /// Get the ID as a string slice
    pub fn as_str(&self) -> &str {
        &self.0
    }

    /// Convert to owned String
    pub fn into_string(self) -> String {
        self.0
    }
}

impl fmt::Display for AccountId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// High-precision timestamp for HFT applications - CANONICAL DEFINITION
///
/// Robust implementation with error handling for financial safety
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default,
)]
pub struct HftTimestamp {
    pub(crate) nanos: u64,
}

impl HftTimestamp {
    /// Get current timestamp with error handling for financial safety
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn now() -> Result<Self, CommonError> {
        use std::time::{SystemTime, UNIX_EPOCH};
        let nanos = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .map_err(|e| CommonError::Service {
                category: CommonErrorCategory::System,
                message: format!("System time before UNIX epoch: {e}"),
            })?
            .as_nanos()
            .try_into()
            .unwrap_or(0_u64);
        Ok(Self { nanos })
    }

    /// Get current timestamp with error handling for financial safety (`CommonTypeError` version)
    ///
    /// # Errors
    /// Returns error if the operation fails
    pub fn now_common() -> Result<Self, CommonTypeError> {
        use std::time::{SystemTime, UNIX_EPOCH};
        let nanos = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .map_err(|e| CommonTypeError::ConversionError {
                message: format!("System time before UNIX epoch: {e}"),
            })?
            .as_nanos()
            .try_into()
            .unwrap_or(0_u64);
        Ok(Self { nanos })
    }

    /// Get current timestamp or zero if system time is invalid
    #[must_use]
    pub fn now_or_zero() -> Self {
        Self::now().unwrap_or(Self { nanos: 0 })
    }

    /// Get nanoseconds since epoch
    #[must_use]
    pub const fn nanos(self) -> u64 {
        self.nanos
    }

    #[allow(clippy::as_conversions)]
    /// Create from nanoseconds since epoch
    #[must_use]
    pub const fn from_nanos(nanos: u64) -> Self {
        Self { nanos }
    }

    /// Create from signed nanoseconds (cast to unsigned)
    #[must_use]
    #[allow(clippy::as_conversions)]
    pub const fn from_nanos_i64(nanos: i64) -> Self {
        Self {
            nanos: nanos as u64,
        }
    }

    /// Get nanoseconds since epoch
    pub const fn as_nanos(&self) -> u64 {
        self.nanos
    }

    /// Convert to `DateTime<Utc>`
    #[allow(clippy::integer_division)]
    pub fn to_datetime(&self) -> DateTime<Utc> {
        let secs = self.nanos / 1_000_000_000;
        let nsecs = u32::try_from(self.nanos % 1_000_000_000).unwrap_or(0);
        DateTime::from_timestamp(i64::try_from(secs).unwrap_or(0), nsecs).unwrap_or_default()
    }
}

impl fmt::Display for HftTimestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.to_datetime())
    }
}

/// Generic timestamp for general use cases
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct GenericTimestamp {
    nanos: u64,
}

impl GenericTimestamp {
    /// Create from nanoseconds since epoch
    #[must_use]
    pub const fn from_nanos(nanos: u64) -> Self {
        Self { nanos }
    }

    /// Get nanoseconds since epoch
    #[must_use]
    pub const fn nanos(&self) -> u64 {
        self.nanos
    }
}
