//! Position builder for testing

use chrono::{DateTime, Utc};

/// Mock position for testing
#[derive(Clone, Debug)]
pub struct MockPosition {
    pub symbol: String,
    pub quantity: f64,
    pub entry_price: f64,
    pub current_price: f64,
    pub timestamp: DateTime<Utc>,
}

impl MockPosition {
    pub fn pnl(&self) -> f64 {
        (self.current_price - self.entry_price) * self.quantity
    }

    pub fn pnl_percent(&self) -> f64 {
        ((self.current_price - self.entry_price) / self.entry_price) * 100.0
    }
}

/// Builder for creating mock positions
pub struct PositionBuilder {
    symbol: String,
    quantity: f64,
    entry_price: f64,
    current_price: f64,
    timestamp: DateTime<Utc>,
}

impl PositionBuilder {
    pub fn new() -> Self {
        Self {
            symbol: "AAPL".to_string(),
            quantity: 100.0,
            entry_price: 150.0,
            current_price: 150.0,
            timestamp: Utc::now(),
        }
    }

    pub fn symbol(mut self, symbol: &str) -> Self {
        self.symbol = symbol.to_string();
        self
    }

    pub fn long(mut self, quantity: f64) -> Self {
        self.quantity = quantity.abs();
        self
    }

    pub fn short(mut self, quantity: f64) -> Self {
        self.quantity = -quantity.abs();
        self
    }

    pub fn entry_price(mut self, price: f64) -> Self {
        self.entry_price = price;
        self
    }

    pub fn current_price(mut self, price: f64) -> Self {
        self.current_price = price;
        self
    }

    pub fn profitable(mut self, percent: f64) -> Self {
        self.current_price = self.entry_price * (1.0 + percent / 100.0);
        self
    }

    pub fn losing(mut self, percent: f64) -> Self {
        self.current_price = self.entry_price * (1.0 - percent / 100.0);
        self
    }

    pub fn build(self) -> MockPosition {
        MockPosition {
            symbol: self.symbol,
            quantity: self.quantity,
            entry_price: self.entry_price,
            current_price: self.current_price,
            timestamp: self.timestamp,
        }
    }
}

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

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_position_builder() {
        let pos = PositionBuilder::new()
            .symbol("TSLA")
            .long(50.0)
            .entry_price(200.0)
            .current_price(220.0)
            .build();

        assert_eq!(pos.symbol, "TSLA");
        assert_eq!(pos.quantity, 50.0);
        assert_eq!(pos.pnl(), 1000.0); // (220 - 200) * 50
        assert_eq!(pos.pnl_percent(), 10.0);
    }

    #[test]
    fn test_short_position() {
        let pos = PositionBuilder::new()
            .short(100.0)
            .entry_price(150.0)
            .current_price(140.0)
            .build();

        assert!(pos.quantity < 0.0);
        assert_eq!(pos.pnl(), -1000.0); // (140 - 150) * -100
    }

    #[test]
    fn test_profitable_position() {
        let pos = PositionBuilder::new()
            .entry_price(100.0)
            .profitable(10.0)
            .build();

        assert_eq!(pos.current_price, 110.0);
        assert_eq!(pos.pnl_percent(), 10.0);
    }

    #[test]
    fn test_losing_position() {
        let pos = PositionBuilder::new()
            .entry_price(100.0)
            .losing(5.0)
            .build();

        assert_eq!(pos.current_price, 95.0);
        assert_eq!(pos.pnl_percent(), -5.0);
    }
}
