"""Risk management engine with stop-loss, position sizing, drawdown limits, and daily loss limits."""

from decimal import Decimal
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from sqlalchemy.orm import Session
from src.core.database import get_database, RiskLimit, Trade, PortfolioSnapshot
from src.core.config import get_config
from src.core.logger import get_logger
from .stop_loss import StopLossManager
from .position_sizing import PositionSizingManager
from .limits import RiskLimitsManager

logger = get_logger(__name__)


class RiskManager:
    """Comprehensive risk management engine."""
    
    def __init__(self):
        """Initialize risk manager."""
        self.db = get_database()
        self.config = get_config()
        self.stop_loss = StopLossManager()
        self.position_sizing = PositionSizingManager()
        self.limits = RiskLimitsManager()
        self.logger = get_logger(__name__)
    
    async def check_order_risk(
        self,
        symbol: str,
        side: str,
        quantity: Decimal,
        price: Decimal,
        current_balance: Decimal,
        exchange_adapter=None
    ) -> tuple[bool, Optional[str]]:
        """Check if order passes risk checks, including fee validation."""
        # Check position sizing (includes fee validation)
        if not self.position_sizing.validate_position_size(
            symbol, quantity, price, current_balance, exchange_adapter
        ):
            return False, "Position size exceeds limits (including fees)"
        
        # Check daily loss limit
        if not await self.limits.check_daily_loss_limit():
            return False, "Daily loss limit reached"
        
        # Check maximum drawdown
        if not await self.limits.check_max_drawdown():
            return False, "Maximum drawdown limit reached"
        
        # Check portfolio allocation
        if not await self.limits.check_portfolio_allocation(symbol, quantity * price):
            return False, "Portfolio allocation limit exceeded"
        
        return True, None
    
    # ... calc position size omitted as it relies on sync position sizing ...
    # Wait, calculate_position_size uses position_sizing which is sync.
    
    async def check_limits(self) -> Dict[str, bool]:
        """Check all risk limits."""
        return {
            'daily_loss': await self.limits.check_daily_loss_limit(),
            'max_drawdown': await self.limits.check_max_drawdown(),
            'position_size': True,  # Checked per order
            'portfolio_allocation': True,  # Checked per order
        }
    
    async def get_risk_metrics(self) -> Dict[str, Any]:
        """Get current risk metrics."""
        return {
            'daily_pnl': await self.limits.get_daily_pnl(),
            'max_drawdown': await self.limits.get_current_drawdown(),
            'portfolio_value': await self.limits.get_portfolio_value(),
            'risk_limits': self.limits.get_all_limits(),  # This call is sync
        }


# Global risk manager
_risk_manager: Optional[RiskManager] = None


def get_risk_manager() -> RiskManager:
    """Get global risk manager instance."""
    global _risk_manager
    if _risk_manager is None:
        _risk_manager = RiskManager()
    return _risk_manager

