"""Portfolio tracking with real-time P&L calculation."""

from decimal import Decimal
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any
from sqlalchemy import select
from src.core.database import get_database, Position, PortfolioSnapshot, Trade
from src.core.logger import get_logger
from src.trading.paper_trading import get_paper_trading

logger = get_logger(__name__)


class PortfolioTracker:
    """Tracks portfolio with real-time P&L calculation."""
    
    def __init__(self):
        """Initialize portfolio tracker."""
        self.db = get_database()
        self.paper_trading = get_paper_trading()
        self.logger = get_logger(__name__)
    
    async def get_current_portfolio(self, paper_trading: bool = True) -> Dict[str, Any]:
        """Get current portfolio state.
        
        Args:
            paper_trading: Paper trading flag
            
        Returns:
            Portfolio dictionary
        """
        if paper_trading:
            performance = self.paper_trading.get_performance()
            positions = self.paper_trading.get_positions()
        else:
            # Live trading - get from database
            async with self.db.get_session() as session:
                stmt = select(Position).where(Position.paper_trading == False)
                result = await session.execute(stmt)
                positions = result.scalars().all()
                
                # Calculate performance from positions
                total_value = Decimal(0)
                unrealized_pnl = Decimal(0)
                for pos in positions:
                    if pos.current_price:
                        pos_value = pos.quantity * pos.current_price
                        total_value += pos_value
                        unrealized_pnl += (pos.current_price - pos.entry_price) * pos.quantity
                
                performance = {
                    "current_value": float(total_value),
                    "unrealized_pnl": float(unrealized_pnl),
                    "realized_pnl": float(sum(pos.realized_pnl for pos in positions)),
                }
        
        return {
            "positions": [
                {
                    "symbol": pos.symbol if hasattr(pos, 'symbol') else pos.symbol,
                    "quantity": float(pos.quantity),
                    "entry_price": float(pos.entry_price),
                    "current_price": float(pos.current_price) if pos.current_price else float(pos.entry_price),
                    "unrealized_pnl": float(pos.unrealized_pnl) if hasattr(pos, 'unrealized_pnl') else 0.0,
                }
                for pos in positions
            ],
            "performance": performance,
            "timestamp": datetime.utcnow().isoformat(),
        }
    
    async def update_positions_prices(self, prices: Dict[str, Decimal], paper_trading: bool = True):
        """Update current prices for positions.
        
        Args:
            prices: Dictionary of symbol -> current_price
            paper_trading: Paper trading flag
        """
        if paper_trading:
            await self.paper_trading.update_positions_prices(prices)
        else:
            async with self.db.get_session() as session:
                try:
                    stmt = select(Position).where(Position.paper_trading == False)
                    result = await session.execute(stmt)
                    positions = result.scalars().all()
                    
                    for pos in positions:
                        if pos.symbol in prices:
                            pos.current_price = prices[pos.symbol]
                            pos.unrealized_pnl = (prices[pos.symbol] - pos.entry_price) * pos.quantity
                            pos.updated_at = datetime.utcnow()
                    await session.commit()
                except Exception as e:
                    await session.rollback()
                    logger.error(f"Failed to update positions prices: {e}")
    
    async def get_portfolio_history(
        self,
        days: int = 30,
        paper_trading: bool = True
    ) -> List[Dict[str, Any]]:
        """Get portfolio history.
        
        Args:
            days: Number of days
            paper_trading: Paper trading flag
            
        Returns:
            List of portfolio snapshots
        """
        async with self.db.get_session() as session:
            since = datetime.utcnow() - timedelta(days=days)
            stmt = select(PortfolioSnapshot).where(
                PortfolioSnapshot.paper_trading == paper_trading,
                PortfolioSnapshot.timestamp >= since
            ).order_by(PortfolioSnapshot.timestamp)
            
            result = await session.execute(stmt)
            snapshots = result.scalars().all()
            
            return [
                {
                    "timestamp": snapshot.timestamp.isoformat(),
                    "total_value": float(snapshot.total_value),
                    "cash": float(snapshot.cash),
                    "positions_value": float(snapshot.positions_value),
                    "unrealized_pnl": float(snapshot.unrealized_pnl),
                    "realized_pnl": float(snapshot.realized_pnl),
                }
                for snapshot in snapshots
            ]


# Global portfolio tracker
_portfolio_tracker: Optional[PortfolioTracker] = None


def get_portfolio_tracker() -> PortfolioTracker:
    """Get global portfolio tracker instance."""
    global _portfolio_tracker
    if _portfolio_tracker is None:
        _portfolio_tracker = PortfolioTracker()
    return _portfolio_tracker
