use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Position {
    pub symbol: String,
    pub quantity: f64,
    pub average_price: f64,
    pub realized_pnl: f64,
    pub unrealized_pnl: f64,
    pub last_update: DateTime<Utc>,
}

impl Position {
    pub fn new(symbol: String) -> Self {
        Self {
            symbol,
            quantity: 0.0,
            average_price: 0.0,
            realized_pnl: 0.0,
            unrealized_pnl: 0.0,
            last_update: Utc::now(),
        }
    }
    
    pub fn is_long(&self) -> bool {
        self.quantity > 0.0
    }
    
    pub fn is_short(&self) -> bool {
        self.quantity < 0.0
    }
    
    pub fn is_flat(&self) -> bool {
        self.quantity.abs() < f64::EPSILON
    }
    
    pub fn market_value(&self, current_price: f64) -> f64 {
        self.quantity * current_price
    }
    
    pub fn calculate_unrealized_pnl(&self, current_price: f64) -> f64 {
        if self.is_flat() {
            0.0
        } else if self.is_long() {
            (current_price - self.average_price) * self.quantity
        } else {
            (self.average_price - current_price) * self.quantity.abs()
        }
    }
}

#[derive(Debug, Clone)]
pub struct PositionUpdate {
    pub symbol: String,
    pub previous_position: Option<Position>,
    pub resulting_position: Position,
    pub realized_pnl: f64,
}