"""Portfolio risk management module for OpenClaw trading system.

This module provides comprehensive portfolio-level risk management including:
- Position concentration limits (single symbol max 20% of portfolio)
- Correlation risk monitoring (avoid high correlation concentration)
- Drawdown control (alert when max drawdown exceeds 10%)
- Value at Risk (VaR) calculations
- Risk interception recording and alerts
"""

from __future__ import annotations

import math
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional, Tuple

import numpy as np

from openclaw.core.economy import SurvivalStatus
from openclaw.utils.logging import get_logger


class RiskAlertLevel(str, Enum):
    """Risk alert severity levels."""

    INFO = "info"
    WARNING = "warning"
    CRITICAL = "critical"
    BLOCK = "block"


@dataclass
class RiskAlert:
    """Risk alert notification.

    Attributes:
        timestamp: When the alert was generated
        alert_type: Type of risk alert
        level: Severity level
        message: Human-readable alert message
        symbol: Related symbol (if applicable)
        current_value: Current risk metric value
        threshold: Threshold that was breached
        action_taken: Action taken in response
    """

    timestamp: datetime
    alert_type: str
    level: RiskAlertLevel
    message: str
    symbol: Optional[str] = None
    current_value: float = 0.0
    threshold: float = 0.0
    action_taken: str = ""


@dataclass
class RiskInterceptionRecord:
    """Record of a risk interception event.

    Attributes:
        timestamp: When the interception occurred
        symbol: Trading symbol (if applicable)
        attempted_action: What action was attempted
        interception_reason: Why it was blocked
        risk_metrics: Risk metrics at time of interception
        suggested_action: Recommended alternative action
    """

    timestamp: datetime
    symbol: Optional[str]
    attempted_action: str
    interception_reason: str
    risk_metrics: Dict[str, Any] = field(default_factory=dict)
    suggested_action: str = ""


@dataclass
class ConcentrationMetrics:
    """Position concentration metrics.

    Attributes:
        symbol: Trading symbol
        position_value: Position value in dollars
        portfolio_value: Total portfolio value
        concentration_pct: Position as percentage of portfolio
        is_breached: Whether concentration limit is breached
    """

    symbol: str
    position_value: float
    portfolio_value: float
    concentration_pct: float
    is_breached: bool


@dataclass
class CorrelationRiskMetrics:
    """Correlation risk metrics for a symbol.

    Attributes:
        symbol: Trading symbol
        correlated_symbols: List of correlated symbols
        avg_correlation: Average correlation with portfolio
        correlation_risk_score: Risk score (0-1)
        is_high_risk: Whether correlation risk is too high
    """

    symbol: str
    correlated_symbols: List[str] = field(default_factory=list)
    avg_correlation: float = 0.0
    correlation_risk_score: float = 0.0
    is_high_risk: bool = False


@dataclass
class DrawdownMetrics:
    """Portfolio drawdown metrics.

    Attributes:
        current_drawdown: Current drawdown percentage
        max_drawdown: Maximum historical drawdown
        drawdown_threshold: Alert threshold
        is_breached: Whether current drawdown exceeds threshold
        peak_value: Peak portfolio value
        trough_value: Lowest value in current drawdown
    """

    current_drawdown: float
    max_drawdown: float
    drawdown_threshold: float
    is_breached: bool
    peak_value: float
    trough_value: float


@dataclass
class VaRMetrics:
    """Value at Risk metrics.

    Attributes:
        portfolio_value: Total portfolio value
        var_95: 95% VaR (1-day)
        var_99: 99% VaR (1-day)
        cvar_95: 95% Conditional VaR (expected shortfall)
        var_pct: VaR as percentage of portfolio
        is_breached: Whether VaR exceeds limit
    """

    portfolio_value: float
    var_95: float
    var_99: float
    cvar_95: float
    var_pct: float
    is_breached: bool


class PositionConcentrationLimit:
    """Monitors and enforces position concentration limits.

    Default limit is 20% of total portfolio value for any single symbol.

    Args:
        max_concentration_pct: Maximum allowed concentration (default 0.20)
        warning_threshold: Warning threshold (default 0.18)
    """

    def __init__(
        self,
        max_concentration_pct: float = 0.20,
        warning_threshold: float = 0.18,
    ):
        self.max_concentration_pct = max_concentration_pct
        self.warning_threshold = warning_threshold
        self.logger = get_logger("portfolio.risk.concentration")

    def check_concentration(
        self,
        symbol: str,
        position_value: float,
        portfolio_value: float,
    ) -> ConcentrationMetrics:
        """Check if a position exceeds concentration limits.

        Args:
            symbol: Trading symbol
            position_value: Position value in dollars
            portfolio_value: Total portfolio value

        Returns:
            ConcentrationMetrics with results
        """
        if portfolio_value <= 0:
            return ConcentrationMetrics(
                symbol=symbol,
                position_value=position_value,
                portfolio_value=0.0,
                concentration_pct=1.0,
                is_breached=True,
            )

        concentration_pct = abs(position_value) / portfolio_value
        is_breached = concentration_pct > self.max_concentration_pct

        metrics = ConcentrationMetrics(
            symbol=symbol,
            position_value=position_value,
            portfolio_value=portfolio_value,
            concentration_pct=concentration_pct,
            is_breached=is_breached,
        )

        if is_breached:
            self.logger.warning(
                f"Concentration limit breached: {symbol} = {concentration_pct:.1%} "
                f"(limit: {self.max_concentration_pct:.1%})"
            )

        return metrics

    def check_all_positions(
        self,
        positions: Dict[str, float],
        portfolio_value: float,
    ) -> List[ConcentrationMetrics]:
        """Check concentration for all positions.

        Args:
            positions: Dictionary mapping symbol to position value
            portfolio_value: Total portfolio value

        Returns:
            List of ConcentrationMetrics for all positions
        """
        return [
            self.check_concentration(symbol, value, portfolio_value)
            for symbol, value in positions.items()
        ]

    def get_max_position_size(self, portfolio_value: float) -> float:
        """Calculate maximum allowed position size.

        Args:
            portfolio_value: Total portfolio value

        Returns:
            Maximum position value allowed
        """
        return portfolio_value * self.max_concentration_pct


class CorrelationRiskMonitor:
    """Monitors correlation risk across portfolio positions.

    Helps avoid concentrating risk in highly correlated assets.

    Args:
        high_correlation_threshold: Threshold for high correlation (default 0.70)
        max_correlated_exposure: Max exposure to highly correlated group (default 0.30)
    """

    def __init__(
        self,
        high_correlation_threshold: float = 0.70,
        max_correlated_exposure: float = 0.30,
    ):
        self.high_correlation_threshold = high_correlation_threshold
        self.max_correlated_exposure = max_correlated_exposure
        self.logger = get_logger("portfolio.risk.correlation")

    def calculate_correlation_matrix(
        self,
        returns_data: Dict[str, List[float]],
    ) -> Dict[str, Dict[str, float]]:
        """Calculate correlation matrix from returns data.

        Args:
            returns_data: Dictionary mapping symbol to returns list

        Returns:
            Correlation matrix as nested dictionary
        """
        symbols = list(returns_data.keys())
        if len(symbols) < 2:
            return {s: {s: 1.0} for s in symbols}

        # Create returns matrix
        returns_matrix = np.array([
            returns_data[s] for s in symbols
        ])

        # Calculate correlation matrix
        corr_matrix = np.corrcoef(returns_matrix)

        # Convert to dictionary format
        correlation_dict = {}
        for i, sym1 in enumerate(symbols):
            correlation_dict[sym1] = {}
            for j, sym2 in enumerate(symbols):
                correlation_dict[sym1][sym2] = float(corr_matrix[i, j])

        return correlation_dict

    def check_correlation_risk(
        self,
        symbol: str,
        positions: Dict[str, float],
        correlations: Dict[str, Dict[str, float]],
    ) -> CorrelationRiskMetrics:
        """Check correlation risk for a symbol.

        Args:
            symbol: Symbol to check
            positions: Current portfolio positions
            correlations: Correlation matrix

        Returns:
            CorrelationRiskMetrics
        """
        if symbol not in positions or len(positions) < 2:
            return CorrelationRiskMetrics(symbol=symbol)

        # Find highly correlated symbols
        correlated_symbols = []
        correlations_sum = 0.0
        count = 0

        for other_symbol in positions.keys():
            if other_symbol == symbol:
                continue

            corr = correlations.get(symbol, {}).get(other_symbol, 0.0)
            correlations_sum += abs(corr)
            count += 1

            if abs(corr) >= self.high_correlation_threshold:
                correlated_symbols.append(other_symbol)

        avg_correlation = correlations_sum / count if count > 0 else 0.0

        # Calculate correlation risk score
        # Higher score = more risk (high correlation + large positions)
        portfolio_value = sum(abs(v) for v in positions.values())
        correlated_exposure = sum(
            abs(positions[s]) for s in correlated_symbols if s in positions
        )

        exposure_pct = correlated_exposure / portfolio_value if portfolio_value > 0 else 0.0
        correlation_risk_score = avg_correlation * exposure_pct

        is_high_risk = (
            len(correlated_symbols) >= 2 or
            exposure_pct > self.max_correlated_exposure
        )

        if is_high_risk:
            self.logger.warning(
                f"High correlation risk for {symbol}: "
                f"{len(correlated_symbols)} correlated symbols, "
                f"exposure={exposure_pct:.1%}"
            )

        return CorrelationRiskMetrics(
            symbol=symbol,
            correlated_symbols=correlated_symbols,
            avg_correlation=avg_correlation,
            correlation_risk_score=correlation_risk_score,
            is_high_risk=is_high_risk,
        )

    def find_correlation_clusters(
        self,
        positions: Dict[str, float],
        correlations: Dict[str, Dict[str, float]],
    ) -> List[List[str]]:
        """Find clusters of highly correlated symbols.

        Args:
            positions: Current portfolio positions
            correlations: Correlation matrix

        Returns:
            List of correlation clusters
        """
        symbols = list(positions.keys())
        visited = set()
        clusters = []

        for symbol in symbols:
            if symbol in visited:
                continue

            cluster = [symbol]
            visited.add(symbol)

            for other in symbols:
                if other in visited:
                    continue

                corr = correlations.get(symbol, {}).get(other, 0.0)
                if abs(corr) >= self.high_correlation_threshold:
                    cluster.append(other)
                    visited.add(other)

            if len(cluster) > 1:
                clusters.append(cluster)

        return clusters


class DrawdownController:
    """Monitors and controls portfolio drawdown.

    Default alert threshold is 10% maximum drawdown.

    Args:
        max_drawdown_threshold: Maximum allowed drawdown (default 0.10)
        warning_threshold: Warning threshold (default 0.07)
    """

    def __init__(
        self,
        max_drawdown_threshold: float = 0.10,
        warning_threshold: float = 0.07,
    ):
        self.max_drawdown_threshold = max_drawdown_threshold
        self.warning_threshold = warning_threshold
        self._peak_value: float = 0.0
        self._trough_value: float = 0.0
        self._max_drawdown: float = 0.0
        self._drawdown_history: List[Tuple[datetime, float]] = []
        self.logger = get_logger("portfolio.risk.drawdown")

    def update(self, portfolio_value: float, timestamp: Optional[datetime] = None) -> DrawdownMetrics:
        """Update drawdown tracking with new portfolio value.

        Args:
            portfolio_value: Current portfolio value
            timestamp: Optional timestamp

        Returns:
            DrawdownMetrics
        """
        if timestamp is None:
            timestamp = datetime.now()

        # Initialize peak if first update
        if self._peak_value == 0.0:
            self._peak_value = portfolio_value
            self._trough_value = portfolio_value

        # Update peak and trough
        if portfolio_value > self._peak_value:
            self._peak_value = portfolio_value
            self._trough_value = portfolio_value
        elif portfolio_value < self._trough_value:
            self._trough_value = portfolio_value

        # Calculate current drawdown
        if self._peak_value > 0:
            current_drawdown = (self._peak_value - portfolio_value) / self._peak_value
        else:
            current_drawdown = 0.0

        # Update max drawdown
        self._max_drawdown = max(self._max_drawdown, current_drawdown)

        # Record history
        self._drawdown_history.append((timestamp, current_drawdown))

        is_breached = current_drawdown > self.max_drawdown_threshold

        if is_breached:
            self.logger.critical(
                f"Max drawdown breached: {current_drawdown:.1%} "
                f"(limit: {self.max_drawdown_threshold:.1%})"
            )
        elif current_drawdown > self.warning_threshold:
            self.logger.warning(
                f"High drawdown warning: {current_drawdown:.1%} "
                f"(warning: {self.warning_threshold:.1%})"
            )

        return DrawdownMetrics(
            current_drawdown=current_drawdown,
            max_drawdown=self._max_drawdown,
            drawdown_threshold=self.max_drawdown_threshold,
            is_breached=is_breached,
            peak_value=self._peak_value,
            trough_value=self._trough_value,
        )

    def is_trading_allowed(self) -> bool:
        """Check if trading should be allowed based on drawdown.

        Returns:
            False if max drawdown is breached
        """
        if not self._drawdown_history:
            return True

        current_drawdown = self._drawdown_history[-1][1]
        return current_drawdown < self.max_drawdown_threshold

    def reset(self, new_peak: Optional[float] = None) -> None:
        """Reset drawdown tracking.

        Args:
            new_peak: Optional new peak value to set
        """
        self._peak_value = new_peak or 0.0
        self._trough_value = new_peak or 0.0
        self._max_drawdown = 0.0
        self._drawdown_history.clear()

    def get_drawdown_history(self) -> List[Tuple[datetime, float]]:
        """Get drawdown history.

        Returns:
            List of (timestamp, drawdown) tuples
        """
        return self._drawdown_history.copy()


class PortfolioVaR:
    """Calculates Value at Risk (VaR) for the portfolio.

    Uses parametric (variance-covariance) method for VaR calculation.

    Args:
        confidence_level: Default confidence level (default 0.95)
        var_limit_pct: Maximum VaR as percentage of portfolio (default 0.05)
    """

    def __init__(
        self,
        confidence_level: float = 0.95,
        var_limit_pct: float = 0.05,
    ):
        self.confidence_level = confidence_level
        self.var_limit_pct = var_limit_pct
        self.logger = get_logger("portfolio.risk.var")

    def calculate_var(
        self,
        portfolio_value: float,
        positions: Dict[str, float],
        volatilities: Dict[str, float],
        correlations: Optional[Dict[str, Dict[str, float]]] = None,
    ) -> VaRMetrics:
        """Calculate portfolio VaR.

        Args:
            portfolio_value: Total portfolio value
            positions: Symbol to position value mapping
            volatilities: Symbol to annualized volatility mapping
            correlations: Optional correlation matrix

        Returns:
            VaRMetrics
        """
        if not positions or portfolio_value <= 0:
            return VaRMetrics(
                portfolio_value=portfolio_value,
                var_95=0.0,
                var_99=0.0,
                cvar_95=0.0,
                var_pct=0.0,
                is_breached=False,
            )

        # Z-scores for confidence levels
        z_95 = 1.645
        z_99 = 2.326

        # Calculate portfolio variance
        symbols = list(positions.keys())
        portfolio_variance = 0.0

        for i, sym1 in enumerate(symbols):
            for j, sym2 in enumerate(symbols):
                vol1 = volatilities.get(sym1, 0.2)
                vol2 = volatilities.get(sym2, 0.2)

                # Daily volatility
                daily_vol1 = vol1 / math.sqrt(252)
                daily_vol2 = vol2 / math.sqrt(252)

                # Correlation
                if i == j:
                    corr = 1.0
                else:
                    corr = correlations.get(sym1, {}).get(sym2, 0.0) if correlations else 0.0

                weight1 = positions[sym1] / portfolio_value
                weight2 = positions[sym2] / portfolio_value

                portfolio_variance += weight1 * weight2 * daily_vol1 * daily_vol2 * corr

        portfolio_volatility = math.sqrt(max(0, portfolio_variance))

        # Calculate VaR
        var_95 = portfolio_value * portfolio_volatility * z_95
        var_99 = portfolio_value * portfolio_volatility * z_99

        # Calculate CVaR (Conditional VaR / Expected Shortfall)
        # Approximation: CVaR = VaR * (1 + z/2) for normal distribution
        cvar_95 = var_95 * 1.4

        var_pct = var_95 / portfolio_value if portfolio_value > 0 else 0.0
        is_breached = var_pct > self.var_limit_pct

        if is_breached:
            self.logger.warning(
                f"VaR limit breached: {var_pct:.2%} (limit: {self.var_limit_pct:.2%})"
            )

        return VaRMetrics(
            portfolio_value=portfolio_value,
            var_95=var_95,
            var_99=var_99,
            cvar_95=cvar_95,
            var_pct=var_pct,
            is_breached=is_breached,
        )

    def calculate_historical_var(
        self,
        portfolio_value: float,
        portfolio_returns: List[float],
        confidence_level: float = 0.95,
    ) -> float:
        """Calculate historical VaR from returns data.

        Args:
            portfolio_value: Total portfolio value
            portfolio_returns: List of historical portfolio returns
            confidence_level: Confidence level

        Returns:
            VaR value in dollars
        """
        if not portfolio_returns:
            return 0.0

        # Sort returns and find the percentile
        sorted_returns = sorted(portfolio_returns)
        index = int(len(sorted_returns) * (1 - confidence_level))
        var_return = sorted_returns[max(0, index)]

        return abs(portfolio_value * var_return)


class PortfolioRiskManager:
    """Main portfolio risk manager that coordinates all risk controls.

    Integrates concentration limits, correlation monitoring, drawdown control,
    and VaR calculations into a unified risk management framework.

    Args:
        portfolio_id: Unique portfolio identifier
        max_concentration_pct: Maximum position concentration
        max_drawdown_pct: Maximum allowed drawdown
        var_limit_pct: Maximum VaR as percentage of portfolio
    """

    def __init__(
        self,
        portfolio_id: str,
        max_concentration_pct: float = 0.20,
        max_drawdown_pct: float = 0.10,
        var_limit_pct: float = 0.05,
    ):
        self.portfolio_id = portfolio_id

        # Initialize risk monitors
        self.concentration_limit = PositionConcentrationLimit(
            max_concentration_pct=max_concentration_pct
        )
        self.correlation_monitor = CorrelationRiskMonitor()
        self.drawdown_controller = DrawdownController(
            max_drawdown_threshold=max_drawdown_pct
        )
        self.var_calculator = PortfolioVaR(var_limit_pct=var_limit_pct)

        # Alert and interception tracking
        self._alerts: List[RiskAlert] = []
        self._interceptions: List[RiskInterceptionRecord] = []

        self.logger = get_logger(f"portfolio.risk.{portfolio_id}")
        self.logger.info(
            f"PortfolioRiskManager initialized: "
            f"max_conc={max_concentration_pct:.0%}, "
            f"max_dd={max_drawdown_pct:.0%}, "
            f"var_limit={var_limit_pct:.0%}"
        )

    def check_trade_risk(
        self,
        symbol: str,
        trade_value: float,
        positions: Dict[str, float],
        portfolio_value: float,
        correlations: Optional[Dict[str, Dict[str, float]]] = None,
    ) -> Tuple[bool, List[RiskAlert], RiskInterceptionRecord]:
        """Check if a proposed trade is allowed based on risk rules.

        Args:
            symbol: Trading symbol
            trade_value: Proposed trade value
            positions: Current positions (after trade)
            portfolio_value: Total portfolio value
            correlations: Optional correlation matrix

        Returns:
            Tuple of (is_allowed, alerts, interception_record)
        """
        alerts: List[RiskAlert] = []
        timestamp = datetime.now()

        # Check drawdown first - most critical
        if not self.drawdown_controller.is_trading_allowed():
            alert = RiskAlert(
                timestamp=timestamp,
                alert_type="max_drawdown",
                level=RiskAlertLevel.BLOCK,
                message=f"Trade blocked: Maximum drawdown exceeded",
                symbol=symbol,
            )
            alerts.append(alert)

            record = RiskInterceptionRecord(
                timestamp=timestamp,
                symbol=symbol,
                attempted_action=f"Trade ${trade_value:,.2f}",
                interception_reason="Maximum drawdown exceeded",
                suggested_action="Reduce positions or wait for recovery",
            )
            self._interceptions.append(record)
            self._alerts.append(alert)
            return False, alerts, record

        # Check concentration limit
        new_position_value = positions.get(symbol, 0.0)
        conc_metrics = self.concentration_limit.check_concentration(
            symbol, new_position_value, portfolio_value
        )

        if conc_metrics.is_breached:
            alert = RiskAlert(
                timestamp=timestamp,
                alert_type="concentration_limit",
                level=RiskAlertLevel.BLOCK,
                message=f"Trade blocked: Concentration limit breached",
                symbol=symbol,
                current_value=conc_metrics.concentration_pct,
                threshold=self.concentration_limit.max_concentration_pct,
            )
            alerts.append(alert)

            record = RiskInterceptionRecord(
                timestamp=timestamp,
                symbol=symbol,
                attempted_action=f"Trade ${trade_value:,.2f}",
                interception_reason=f"Concentration limit: {conc_metrics.concentration_pct:.1%}",
                risk_metrics={"concentration_pct": conc_metrics.concentration_pct},
                suggested_action=f"Reduce position below {self.concentration_limit.max_concentration_pct:.1%}",
            )
            self._interceptions.append(record)
            self._alerts.append(alert)
            return False, alerts, record

        # Check correlation risk
        if correlations:
            corr_metrics = self.correlation_monitor.check_correlation_risk(
                symbol, positions, correlations
            )
            if corr_metrics.is_high_risk:
                alert = RiskAlert(
                    timestamp=timestamp,
                    alert_type="correlation_risk",
                    level=RiskAlertLevel.WARNING,
                    message=f"High correlation risk detected",
                    symbol=symbol,
                    current_value=corr_metrics.correlation_risk_score,
                )
                alerts.append(alert)
                self._alerts.append(alert)

        # If we have warnings but not blocks, allow with caution
        is_allowed = not any(a.level == RiskAlertLevel.BLOCK for a in alerts)

        record = RiskInterceptionRecord(
            timestamp=timestamp,
            symbol=symbol,
            attempted_action=f"Trade ${trade_value:,.2f}",
            interception_reason="" if is_allowed else "Risk limits breached",
            risk_metrics={"alerts_count": len(alerts)},
        )

        if not is_allowed:
            self._interceptions.append(record)

        return is_allowed, alerts, record

    def update_portfolio_risk(
        self,
        portfolio_value: float,
        positions: Dict[str, float],
        volatilities: Optional[Dict[str, float]] = None,
        correlations: Optional[Dict[str, Dict[str, float]]] = None,
        timestamp: Optional[datetime] = None,
    ) -> Dict[str, Any]:
        """Update all portfolio risk metrics.

        Args:
            portfolio_value: Current portfolio value
            positions: Current positions
            volatilities: Symbol volatilities
            correlations: Correlation matrix
            timestamp: Optional timestamp

        Returns:
            Dictionary with all risk metrics
        """
        if timestamp is None:
            timestamp = datetime.now()

        # Update drawdown
        drawdown_metrics = self.drawdown_controller.update(portfolio_value, timestamp)

        # Check concentration for all positions
        concentration_metrics = self.concentration_limit.check_all_positions(
            positions, portfolio_value
        )

        # Calculate VaR
        volatilities = volatilities or {}
        var_metrics = self.var_calculator.calculate_var(
            portfolio_value, positions, volatilities, correlations
        )

        # Check for alerts
        if drawdown_metrics.is_breached:
            self._alerts.append(RiskAlert(
                timestamp=timestamp,
                alert_type="drawdown",
                level=RiskAlertLevel.CRITICAL,
                message=f"Maximum drawdown breached: {drawdown_metrics.current_drawdown:.1%}",
                current_value=drawdown_metrics.current_drawdown,
                threshold=drawdown_metrics.drawdown_threshold,
            ))

        if var_metrics.is_breached:
            self._alerts.append(RiskAlert(
                timestamp=timestamp,
                alert_type="var_limit",
                level=RiskAlertLevel.WARNING,
                message=f"VaR limit breached: {var_metrics.var_pct:.2%}",
                current_value=var_metrics.var_pct,
                threshold=self.var_calculator.var_limit_pct,
            ))

        return {
            "timestamp": timestamp.isoformat(),
            "portfolio_value": portfolio_value,
            "drawdown": drawdown_metrics,
            "concentration": concentration_metrics,
            "var": var_metrics,
            "alert_count": len(self._alerts),
        }

    def get_alerts(
        self,
        level: Optional[RiskAlertLevel] = None,
        since: Optional[datetime] = None,
    ) -> List[RiskAlert]:
        """Get risk alerts.

        Args:
            level: Filter by alert level
            since: Filter by time

        Returns:
            List of matching alerts
        """
        alerts = self._alerts

        if level:
            alerts = [a for a in alerts if a.level == level]

        if since:
            alerts = [a for a in alerts if a.timestamp >= since]

        return alerts

    def get_interceptions(self, since: Optional[datetime] = None) -> List[RiskInterceptionRecord]:
        """Get risk interception records.

        Args:
            since: Filter by time

        Returns:
            List of interception records
        """
        if since:
            return [r for r in self._interceptions if r.timestamp >= since]
        return self._interceptions.copy()

    def clear_alerts(self) -> None:
        """Clear all alerts."""
        self._alerts.clear()

    def get_risk_summary(self) -> Dict[str, Any]:
        """Get summary of current risk status.

        Returns:
            Risk summary dictionary
        """
        recent_alerts = [
            a for a in self._alerts
            if (datetime.now() - a.timestamp).days < 1
        ]

        critical_count = sum(1 for a in recent_alerts if a.level == RiskAlertLevel.CRITICAL)
        warning_count = sum(1 for a in recent_alerts if a.level == RiskAlertLevel.WARNING)
        block_count = sum(1 for a in self._interceptions[-10:])

        return {
            "portfolio_id": self.portfolio_id,
            "is_trading_allowed": self.drawdown_controller.is_trading_allowed(),
            "recent_alerts": len(recent_alerts),
            "critical_alerts": critical_count,
            "warning_alerts": warning_count,
            "recent_interceptions": block_count,
            "config": {
                "max_concentration": self.concentration_limit.max_concentration_pct,
                "max_drawdown": self.drawdown_controller.max_drawdown_threshold,
                "var_limit": self.var_calculator.var_limit_pct,
            },
        }
