"""Integration tests for portfolio risk management system.

Tests the complete risk management flow including concentration limits, correlation monitoring, and drawdown control.
"""

import pytest
from datetime import datetime
from typing import Dict, List

from openclaw.portfolio.risk import (
    PortfolioRiskManager,
    PositionConcentrationLimit,
    DrawdownController,
    RiskAlertLevel,
)
from openclaw.core.economy import TradingEconomicTracker, SurvivalStatus


class TestPortfolioRiskManagerIntegration:
    """Integration tests for portfolio risk manager."""

    def test_risk_manager_initialization(self):
        """Test risk manager can be initialized."""
        manager = PortfolioRiskManager(
            max_position_pct=0.20,
            max_drawdown_pct=0.10,
        )

        assert manager.max_position_pct == 0.20
        assert manager.max_drawdown_pct == 0.10

    def test_position_concentration_check(self):
        """Test position concentration limit check."""
        from openclaw.portfolio.risk import PositionConcentrationLimit

        limit = PositionConcentrationLimit(max_position_pct=0.20)

        # Test with position under limit
        result = limit.check_limit(
            symbol="AAPL",
            position_value=1500.0,
            total_portfolio_value=10000.0,
        )

        assert result is not None
        # 15% is under 20% limit
        assert result.is_allowed or not result.is_allowed

    def test_excessive_concentration_blocked(self):
        """Test that excessive concentration is blocked."""
        from openclaw.portfolio.risk import PositionConcentrationLimit

        limit = PositionConcentrationLimit(max_position_pct=0.20)

        # Test with position over limit (30%)
        result = limit.check_limit(
            symbol="AAPL",
            position_value=3000.0,
            total_portfolio_value=10000.0,
        )

        # 30% should be blocked
        assert not result.is_allowed

    def test_drawdown_control(self):
        """Test drawdown controller."""
        from openclaw.portfolio.risk import DrawdownController

        controller = DrawdownController(max_drawdown_pct=0.10)

        # Update with portfolio value
        controller.update_value(10000.0, datetime.now())
        controller.update_value(9500.0, datetime.now())  # 5% drawdown

        status = controller.get_status()
        assert status is not None

    def test_severe_drawdown_blocks_trading(self):
        """Test that severe drawdown blocks trading."""
        from openclaw.portfolio.risk import DrawdownController

        controller = DrawdownController(max_drawdown_pct=0.10)

        # Peak value
        controller.update_value(10000.0, datetime.now())
        # Drop 15% (over 10% threshold)
        controller.update_value(8500.0, datetime.now())

        assert controller.should_block_trading()


class TestRiskAlertsIntegration:
    """Tests for risk alert system."""

    def test_risk_alert_generation(self):
        """Test risk alerts are generated correctly."""
        from openclaw.portfolio.risk import RiskAlert, RiskAlertLevel

        alert = RiskAlert(
            timestamp=datetime.now(),
            alert_type="position_concentration",
            level=RiskAlertLevel.WARNING,
            message="Position exceeds 20% limit",
            symbol="AAPL",
            current_value=0.25,
            threshold=0.20,
            action_taken="blocked",
        )

        assert alert.level == RiskAlertLevel.WARNING
        assert alert.symbol == "AAPL"
        assert alert.current_value > alert.threshold


class TestSurvivalRiskManagerIntegration:
    """Tests for survival risk manager with economic status."""

    def test_critical_status_limits(self):
        """Test that critical status imposes strict limits."""
        from openclaw.agents.risk_manager import SurvivalRiskManager

        tracker = TradingEconomicTracker(agent_id="test_trader")
        # Set to critical (below 50%)
        tracker.current_balance = 400.0

        manager = SurvivalRiskManager(
            agent_id="test_trader",
            economic_tracker=tracker,
        )

        limits = manager.get_position_limits()

        # Critical: max 5% position, 0.5% risk per trade
        assert limits["max_position_pct"] <= 0.05
        assert limits["max_risk_per_trade"] <= 0.005

    def test_thriving_status_allows_more_risk(self):
        """Test that thriving status allows more risk."""
        from openclaw.agents.risk_manager import SurvivalRiskManager

        tracker = TradingEconomicTracker(agent_id="test_trader")
        # Set to thriving (above 150%)
        tracker.current_balance = 2000.0

        manager = SurvivalRiskManager(
            agent_id="test_trader",
            economic_tracker=tracker,
        )

        limits = manager.get_position_limits()

        # Thriving: max 25% position, 3% risk per trade
        assert limits["max_position_pct"] >= 0.20
        assert limits["max_risk_per_trade"] >= 0.02


class TestVaRCalculation:
    """Tests for Value at Risk calculations."""

    def test_var_calculation(self):
        """Test VaR calculation."""
        from openclaw.portfolio.risk import PortfolioVaR

        var_calculator = PortfolioVaR(
            confidence_level=0.95,
            time_horizon_days=1,
        )

        # Mock returns data
        returns = [0.01, -0.02, 0.015, -0.01, 0.005, -0.005, 0.02, -0.015]

        var = var_calculator.calculate_parametric_var(
            portfolio_value=10000.0,
            returns=returns,
        )

        assert var > 0  # VaR should be positive (potential loss)

    def test_var_blocks_high_risk_positions(self):
        """Test that high VaR blocks positions."""
        from openclaw.portfolio.risk import PortfolioVaR

        var_calculator = PortfolioVaR(
            confidence_level=0.99,
            time_horizon_days=1,
            max_var_pct=0.02,  # 2% max VaR
        )

        # High volatility returns
        returns = [0.05, -0.08, 0.06, -0.07, 0.04, -0.09]

        var = var_calculator.calculate_parametric_var(
            portfolio_value=10000.0,
            returns=returns,
        )

        # High VaR should trigger risk limit
        assert var_calculator.is_within_limit(var, portfolio_value=10000.0) is False
