using NT8.Core.Common.Models;
using NT8.Core.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NT8.Core.Risk
{
    /// <summary>
    /// Advanced risk manager implementing Tier 2-3 risk controls
    /// Wraps BasicRiskManager and adds weekly limits, drawdown tracking, and correlation checks
    /// Thread-safe implementation using locks for state consistency
    /// </summary>
    public class AdvancedRiskManager : IRiskManager
    {
        private readonly ILogger _logger;
        private readonly BasicRiskManager _basicRiskManager;
        private readonly object _lock = new object();

        // Advanced risk state - protected by _lock
        private AdvancedRiskState _state;
        private AdvancedRiskConfig _advancedConfig;
        private DateTime _weekStartDate;
        private DateTime _lastConfigUpdate;

        // Strategy tracking for cross-strategy exposure
        private readonly Dictionary<string, StrategyExposure> _strategyExposures = new Dictionary<string, StrategyExposure>();

        // Symbol correlation matrix for correlation-based limits
        private readonly Dictionary<string, Dictionary<string, double>> _correlationMatrix = new Dictionary<string, Dictionary<string, double>>();

        /// <summary>
        /// Constructor for AdvancedRiskManager
        /// </summary>
        /// <param name="logger">Logger instance</param>
        /// <param name="basicRiskManager">Basic risk manager for Tier 1 checks</param>
        /// <param name="advancedConfig">Advanced risk configuration</param>
        /// <exception cref="ArgumentNullException">Required parameter is null</exception>
        public AdvancedRiskManager(
            ILogger logger,
            BasicRiskManager basicRiskManager,
            AdvancedRiskConfig advancedConfig)
        {
            if (logger == null) throw new ArgumentNullException("logger");
            if (basicRiskManager == null) throw new ArgumentNullException("basicRiskManager");
            if (advancedConfig == null) throw new ArgumentNullException("advancedConfig");

            _logger = logger;
            _basicRiskManager = basicRiskManager;
            _advancedConfig = advancedConfig;
            _weekStartDate = GetWeekStart(DateTime.UtcNow);
            _lastConfigUpdate = DateTime.UtcNow;

            // Initialize advanced state
            _state = new AdvancedRiskState(
                weeklyPnL: 0,
                weekStartDate: _weekStartDate,
                trailingDrawdown: 0,
                peakEquity: 0,
                activeStrategies: new List<string>(),
                exposureBySymbol: new Dictionary<string, double>(),
                correlatedExposure: 0,
                lastStateUpdate: DateTime.UtcNow
            );

            _logger.LogInformation("AdvancedRiskManager initialized with config: WeeklyLimit={0:C}, DrawdownLimit={1:C}",
                advancedConfig.WeeklyLossLimit, advancedConfig.TrailingDrawdownLimit);
        }

        /// <summary>
        /// Validate order intent through all risk tiers
        /// </summary>
        public RiskDecision ValidateOrder(StrategyIntent intent, StrategyContext context, RiskConfig config)
        {
            if (intent == null) throw new ArgumentNullException("intent");
            if (context == null) throw new ArgumentNullException("context");
            if (config == null) throw new ArgumentNullException("config");

            try
            {
                // Tier 1: Basic risk checks (delegate to BasicRiskManager)
                var basicDecision = _basicRiskManager.ValidateOrder(intent, context, config);
                if (!basicDecision.Allow)
                {
                    _logger.LogWarning("Order rejected by Tier 1 risk: {0}", basicDecision.RejectReason);
                    return basicDecision;
                }

                lock (_lock)
                {
                    // Check if week has rolled over
                    CheckWeekRollover();

                    // Tier 2: Weekly loss limit
                    var weeklyCheck = ValidateWeeklyLimit(intent, context);
                    if (!weeklyCheck.Allow)
                    {
                        return weeklyCheck;
                    }

                    // Tier 2: Trailing drawdown limit
                    var drawdownCheck = ValidateTrailingDrawdown(intent, context);
                    if (!drawdownCheck.Allow)
                    {
                        return drawdownCheck;
                    }

                    // Tier 3: Cross-strategy exposure
                    var exposureCheck = ValidateCrossStrategyExposure(intent, context);
                    if (!exposureCheck.Allow)
                    {
                        return exposureCheck;
                    }

                    // Tier 3: Time-based restrictions
                    var timeCheck = ValidateTimeRestrictions(intent, context);
                    if (!timeCheck.Allow)
                    {
                        return timeCheck;
                    }

                    // Tier 3: Correlation-based limits
                    var correlationCheck = ValidateCorrelationLimits(intent, context);
                    if (!correlationCheck.Allow)
                    {
                        return correlationCheck;
                    }

                    // All checks passed - combine metrics
                    var riskLevel = DetermineAdvancedRiskLevel();
                    var combinedMetrics = CombineMetrics(basicDecision.RiskMetrics);

                    _logger.LogDebug("Order approved through all risk tiers: {0} {1}, Level={2}",
                        intent.Symbol, intent.Side, riskLevel);

                    return new RiskDecision(
                        allow: true,
                        rejectReason: null,
                        modifiedIntent: null,
                        riskLevel: riskLevel,
                        riskMetrics: combinedMetrics
                    );
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Risk validation error: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Validate weekly loss limit (Tier 2)
        /// </summary>
        private RiskDecision ValidateWeeklyLimit(StrategyIntent intent, StrategyContext context)
        {
            if (_state.WeeklyPnL <= -_advancedConfig.WeeklyLossLimit)
            {
                _logger.LogCritical("Weekly loss limit breached: {0:C} <= {1:C}",
                    _state.WeeklyPnL, -_advancedConfig.WeeklyLossLimit);

                var metrics = new Dictionary<string, object>();
                metrics.Add("weekly_pnl", _state.WeeklyPnL);
                metrics.Add("weekly_limit", _advancedConfig.WeeklyLossLimit);
                metrics.Add("week_start", _state.WeekStartDate);

                return new RiskDecision(
                    allow: false,
                    rejectReason: String.Format("Weekly loss limit breached: {0:C}", _state.WeeklyPnL),
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Critical,
                    riskMetrics: metrics
                );
            }

            // Warning at 80% of weekly limit
            if (_state.WeeklyPnL <= -(_advancedConfig.WeeklyLossLimit * 0.8))
            {
                _logger.LogWarning("Approaching weekly loss limit: {0:C} (80% threshold)",
                    _state.WeeklyPnL);
            }

            return new RiskDecision(
                allow: true,
                rejectReason: null,
                modifiedIntent: null,
                riskLevel: RiskLevel.Low,
                riskMetrics: new Dictionary<string, object>()
            );
        }

        /// <summary>
        /// Validate trailing drawdown limit (Tier 2)
        /// </summary>
        private RiskDecision ValidateTrailingDrawdown(StrategyIntent intent, StrategyContext context)
        {
            var currentDrawdown = _state.PeakEquity - context.Account.Equity;

            if (currentDrawdown >= _advancedConfig.TrailingDrawdownLimit)
            {
                _logger.LogCritical("Trailing drawdown limit breached: {0:C} >= {1:C}",
                    currentDrawdown, _advancedConfig.TrailingDrawdownLimit);

                var metrics = new Dictionary<string, object>();
                metrics.Add("trailing_drawdown", currentDrawdown);
                metrics.Add("drawdown_limit", _advancedConfig.TrailingDrawdownLimit);
                metrics.Add("peak_equity", _state.PeakEquity);
                metrics.Add("current_balance", context.Account.Equity);

                return new RiskDecision(
                    allow: false,
                    rejectReason: String.Format("Trailing drawdown limit breached: {0:C}", currentDrawdown),
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Critical,
                    riskMetrics: metrics
                );
            }

            return new RiskDecision(
                allow: true,
                rejectReason: null,
                modifiedIntent: null,
                riskLevel: RiskLevel.Low,
                riskMetrics: new Dictionary<string, object>()
            );
        }

        /// <summary>
        /// Validate cross-strategy exposure limits (Tier 3)
        /// </summary>
        private RiskDecision ValidateCrossStrategyExposure(StrategyIntent intent, StrategyContext context)
        {
            if (!_advancedConfig.MaxCrossStrategyExposure.HasValue)
            {
                return new RiskDecision(
                    allow: true,
                    rejectReason: null,
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Low,
                    riskMetrics: new Dictionary<string, object>()
                );
            }

            // Calculate total exposure across all strategies for this symbol
            var symbolExposure = 0.0;
            if (_state.ExposureBySymbol.ContainsKey(intent.Symbol))
            {
                symbolExposure = _state.ExposureBySymbol[intent.Symbol];
            }

            // Calculate new exposure from this intent
            var intentExposure = CalculateIntentExposure(intent, context);
            var totalExposure = Math.Abs(symbolExposure + intentExposure);

            if (totalExposure > _advancedConfig.MaxCrossStrategyExposure.Value)
            {
                _logger.LogWarning("Cross-strategy exposure limit exceeded: {0:C} > {1:C}",
                    totalExposure, _advancedConfig.MaxCrossStrategyExposure.Value);

                var metrics = new Dictionary<string, object>();
                metrics.Add("symbol", intent.Symbol);
                metrics.Add("current_exposure", symbolExposure);
                metrics.Add("intent_exposure", intentExposure);
                metrics.Add("total_exposure", totalExposure);
                metrics.Add("exposure_limit", _advancedConfig.MaxCrossStrategyExposure.Value);

                return new RiskDecision(
                    allow: false,
                    rejectReason: String.Format("Cross-strategy exposure limit exceeded for {0}", intent.Symbol),
                    modifiedIntent: null,
                    riskLevel: RiskLevel.High,
                    riskMetrics: metrics
                );
            }

            return new RiskDecision(
                allow: true,
                rejectReason: null,
                modifiedIntent: null,
                riskLevel: RiskLevel.Low,
                riskMetrics: new Dictionary<string, object>()
            );
        }

        /// <summary>
        /// Validate time-based trading restrictions (Tier 3)
        /// </summary>
        private RiskDecision ValidateTimeRestrictions(StrategyIntent intent, StrategyContext context)
        {
            if (_advancedConfig.TradingTimeWindows == null || _advancedConfig.TradingTimeWindows.Count == 0)
            {
                return new RiskDecision(
                    allow: true,
                    rejectReason: null,
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Low,
                    riskMetrics: new Dictionary<string, object>()
                );
            }

            var currentTime = DateTime.UtcNow.TimeOfDay;
            var isInWindow = false;

            foreach (var window in _advancedConfig.TradingTimeWindows)
            {
                if (currentTime >= window.StartTime && currentTime <= window.EndTime)
                {
                    isInWindow = true;
                    break;
                }
            }

            if (!isInWindow)
            {
                _logger.LogWarning("Order outside trading time windows: {0}", currentTime);

                var metrics = new Dictionary<string, object>();
                metrics.Add("current_time", currentTime.ToString());
                metrics.Add("time_windows", _advancedConfig.TradingTimeWindows.Count);

                return new RiskDecision(
                    allow: false,
                    rejectReason: "Order outside allowed trading time windows",
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Medium,
                    riskMetrics: metrics
                );
            }

            return new RiskDecision(
                allow: true,
                rejectReason: null,
                modifiedIntent: null,
                riskLevel: RiskLevel.Low,
                riskMetrics: new Dictionary<string, object>()
            );
        }

        /// <summary>
        /// Validate correlation-based exposure limits (Tier 3)
        /// </summary>
        private RiskDecision ValidateCorrelationLimits(StrategyIntent intent, StrategyContext context)
        {
            if (!_advancedConfig.MaxCorrelatedExposure.HasValue)
            {
                return new RiskDecision(
                    allow: true,
                    rejectReason: null,
                    modifiedIntent: null,
                    riskLevel: RiskLevel.Low,
                    riskMetrics: new Dictionary<string, object>()
                );
            }

            // Calculate correlated exposure
            var correlatedExposure = CalculateCorrelatedExposure(intent, context);

            if (correlatedExposure > _advancedConfig.MaxCorrelatedExposure.Value)
            {
                _logger.LogWarning("Correlated exposure limit exceeded: {0:C} > {1:C}",
                    correlatedExposure, _advancedConfig.MaxCorrelatedExposure.Value);

                var metrics = new Dictionary<string, object>();
                metrics.Add("correlated_exposure", correlatedExposure);
                metrics.Add("correlation_limit", _advancedConfig.MaxCorrelatedExposure.Value);
                metrics.Add("symbol", intent.Symbol);

                return new RiskDecision(
                    allow: false,
                    rejectReason: "Correlated exposure limit exceeded",
                    modifiedIntent: null,
                    riskLevel: RiskLevel.High,
                    riskMetrics: metrics
                );
            }

            return new RiskDecision(
                allow: true,
                rejectReason: null,
                modifiedIntent: null,
                riskLevel: RiskLevel.Low,
                riskMetrics: new Dictionary<string, object>()
            );
        }

        /// <summary>
        /// Calculate exposure from intent
        /// </summary>
        private static double CalculateIntentExposure(StrategyIntent intent, StrategyContext context)
        {
            // Get tick value for symbol
            var tickValue = GetTickValue(intent.Symbol);

            // For intent, we need to estimate quantity based on stop ticks
            // In Phase 2, this will be calculated by position sizer
            // For now, use a conservative estimate of 1 contract
            var estimatedQuantity = 1;

            // Calculate dollar exposure
            var exposure = estimatedQuantity * intent.StopTicks * tickValue;

            // Apply direction
            if (intent.Side == Common.Models.OrderSide.Sell)
            {
                exposure = -exposure;
            }

            return exposure;
        }

        /// <summary>
        /// Calculate correlated exposure across portfolio
        /// </summary>
        private double CalculateCorrelatedExposure(StrategyIntent intent, StrategyContext context)
        {
            var totalCorrelatedExposure = 0.0;

            // Get correlation coefficients for this symbol
            if (!_correlationMatrix.ContainsKey(intent.Symbol))
            {
                // No correlation data - return current exposure only
                return CalculateIntentExposure(intent, context);
            }

            var correlations = _correlationMatrix[intent.Symbol];

            // Calculate weighted exposure based on correlations
            foreach (var exposure in _state.ExposureBySymbol)
            {
                var symbol = exposure.Key;
                var symbolExposure = exposure.Value;

                if (correlations.ContainsKey(symbol))
                {
                    var correlation = correlations[symbol];
                    totalCorrelatedExposure += symbolExposure * correlation;
                }
            }

            // Add current intent exposure
            totalCorrelatedExposure += CalculateIntentExposure(intent, context);

            return Math.Abs(totalCorrelatedExposure);
        }

        /// <summary>
        /// Get tick value for symbol
        /// </summary>
        private static double GetTickValue(string symbol)
        {
            // Static tick values - will be enhanced with dynamic lookup in future phases
            switch (symbol)
            {
                case "ES": return 12.50;
                case "MES": return 1.25;
                case "NQ": return 5.00;
                case "MNQ": return 0.50;
                case "CL": return 10.00;
                case "GC": return 10.00;
                default: return 12.50; // Default to ES
            }
        }

        /// <summary>
        /// Determine advanced risk level based on current state
        /// </summary>
        private RiskLevel DetermineAdvancedRiskLevel()
        {
            // Check weekly loss percentage
            var weeklyLossPercent = Math.Abs(_state.WeeklyPnL) / _advancedConfig.WeeklyLossLimit;
            if (weeklyLossPercent >= 0.8) return RiskLevel.High;
            if (weeklyLossPercent >= 0.5) return RiskLevel.Medium;

            // Check trailing drawdown percentage
            if (_state.PeakEquity > 0)
            {
                var drawdownPercent = _state.TrailingDrawdown / _advancedConfig.TrailingDrawdownLimit;
                if (drawdownPercent >= 0.8) return RiskLevel.High;
                if (drawdownPercent >= 0.5) return RiskLevel.Medium;
            }

            return RiskLevel.Low;
        }

        /// <summary>
        /// Combine metrics from basic and advanced checks
        /// </summary>
        private Dictionary<string, object> CombineMetrics(Dictionary<string, object> basicMetrics)
        {
            var combined = new Dictionary<string, object>(basicMetrics);

            combined.Add("weekly_pnl", _state.WeeklyPnL);
            combined.Add("week_start", _state.WeekStartDate);
            combined.Add("trailing_drawdown", _state.TrailingDrawdown);
            combined.Add("peak_equity", _state.PeakEquity);
            combined.Add("active_strategies", _state.ActiveStrategies.Count);
            combined.Add("correlated_exposure", _state.CorrelatedExposure);

            return combined;
        }

        /// <summary>
        /// Check if week has rolled over and reset weekly state if needed
        /// </summary>
        private void CheckWeekRollover()
        {
            var currentWeekStart = GetWeekStart(DateTime.UtcNow);

            if (currentWeekStart > _weekStartDate)
            {
                _logger.LogInformation("Week rollover detected: {0} -> {1}",
                    _weekStartDate, currentWeekStart);

                _weekStartDate = currentWeekStart;
                _state = new AdvancedRiskState(
                    weeklyPnL: 0,
                    weekStartDate: _weekStartDate,
                    trailingDrawdown: _state.TrailingDrawdown,
                    peakEquity: _state.PeakEquity,
                    activeStrategies: _state.ActiveStrategies,
                    exposureBySymbol: _state.ExposureBySymbol,
                    correlatedExposure: _state.CorrelatedExposure,
                    lastStateUpdate: DateTime.UtcNow
                );
            }
        }

        /// <summary>
        /// Get start of week (Monday 00:00 UTC)
        /// </summary>
        private static DateTime GetWeekStart(DateTime date)
        {
            var daysToSubtract = ((int)date.DayOfWeek - (int)DayOfWeek.Monday + 7) % 7;
            return date.Date.AddDays(-daysToSubtract);
        }

        /// <summary>
        /// Update risk state after fill
        /// </summary>
        public void OnFill(OrderFill fill)
        {
            if (fill == null) throw new ArgumentNullException("fill");

            try
            {
                // Delegate to basic risk manager
                _basicRiskManager.OnFill(fill);

                lock (_lock)
                {
                    // Update symbol exposure
                    var fillValue = fill.Quantity * fill.FillPrice;

                    if (_state.ExposureBySymbol.ContainsKey(fill.Symbol))
                    {
                        var newExposure = _state.ExposureBySymbol[fill.Symbol] + fillValue;
                        var updatedExposures = new Dictionary<string, double>(_state.ExposureBySymbol);
                        updatedExposures[fill.Symbol] = newExposure;

                        _state = new AdvancedRiskState(
                            weeklyPnL: _state.WeeklyPnL,
                            weekStartDate: _state.WeekStartDate,
                            trailingDrawdown: _state.TrailingDrawdown,
                            peakEquity: _state.PeakEquity,
                            activeStrategies: _state.ActiveStrategies,
                            exposureBySymbol: updatedExposures,
                            correlatedExposure: _state.CorrelatedExposure,
                            lastStateUpdate: DateTime.UtcNow
                        );
                    }
                    else
                    {
                        var updatedExposures = new Dictionary<string, double>(_state.ExposureBySymbol);
                        updatedExposures.Add(fill.Symbol, fillValue);

                        _state = new AdvancedRiskState(
                            weeklyPnL: _state.WeeklyPnL,
                            weekStartDate: _state.WeekStartDate,
                            trailingDrawdown: _state.TrailingDrawdown,
                            peakEquity: _state.PeakEquity,
                            activeStrategies: _state.ActiveStrategies,
                            exposureBySymbol: updatedExposures,
                            correlatedExposure: _state.CorrelatedExposure,
                            lastStateUpdate: DateTime.UtcNow
                        );
                    }

                    _logger.LogDebug("Fill processed: {0} {1} @ {2:F2}, Exposure: {3:C}",
                        fill.Symbol, fill.Quantity, fill.FillPrice, _state.ExposureBySymbol[fill.Symbol]);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Error processing fill: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Update risk state after P&L change
        /// </summary>
        public void OnPnLUpdate(double netPnL, double dayPnL)
        {
            try
            {
                // Delegate to basic risk manager
                _basicRiskManager.OnPnLUpdate(netPnL, dayPnL);

                lock (_lock)
                {
                    CheckWeekRollover();

                    var oldWeeklyPnL = _state.WeeklyPnL;
                    var oldPeakEquity = _state.PeakEquity;

                    // Update weekly P&L (accumulate daily changes)
                    var dailyChange = dayPnL; // This represents the change for today
                    var newWeeklyPnL = _state.WeeklyPnL + dailyChange;

                    // Update peak equity and trailing drawdown
                    var newPeakEquity = Math.Max(_state.PeakEquity, netPnL);
                    var newDrawdown = newPeakEquity - netPnL;

                    _state = new AdvancedRiskState(
                        weeklyPnL: newWeeklyPnL,
                        weekStartDate: _state.WeekStartDate,
                        trailingDrawdown: newDrawdown,
                        peakEquity: newPeakEquity,
                        activeStrategies: _state.ActiveStrategies,
                        exposureBySymbol: _state.ExposureBySymbol,
                        correlatedExposure: _state.CorrelatedExposure,
                        lastStateUpdate: DateTime.UtcNow
                    );

                    if (Math.Abs(newWeeklyPnL - oldWeeklyPnL) > 0.01 || Math.Abs(newPeakEquity - oldPeakEquity) > 0.01)
                    {
                        _logger.LogDebug("P&L Update: Weekly={0:C}, Trailing DD={1:C}, Peak={2:C}",
                            newWeeklyPnL, newDrawdown, newPeakEquity);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Error updating P&L: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Emergency flatten all positions
        /// </summary>
        public async Task<bool> EmergencyFlatten(string reason)
        {
            if (String.IsNullOrEmpty(reason)) throw new ArgumentException("Reason required", "reason");

            try
            {
                _logger.LogCritical("Advanced emergency flatten triggered: {0}", reason);

                // Delegate to basic risk manager
                var result = await _basicRiskManager.EmergencyFlatten(reason);

                lock (_lock)
                {
                    // Clear all exposures
                    _state = new AdvancedRiskState(
                        weeklyPnL: _state.WeeklyPnL,
                        weekStartDate: _state.WeekStartDate,
                        trailingDrawdown: _state.TrailingDrawdown,
                        peakEquity: _state.PeakEquity,
                        activeStrategies: new List<string>(),
                        exposureBySymbol: new Dictionary<string, double>(),
                        correlatedExposure: 0,
                        lastStateUpdate: DateTime.UtcNow
                    );

                    _strategyExposures.Clear();
                }

                _logger.LogInformation("Advanced emergency flatten completed");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError("Emergency flatten failed: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Get current risk status
        /// </summary>
        public RiskStatus GetRiskStatus()
        {
            try
            {
                // Get basic status first
                var basicStatus = _basicRiskManager.GetRiskStatus();

                lock (_lock)
                {
                    CheckWeekRollover();

                    var alerts = new List<string>(basicStatus.ActiveAlerts);

                    // Add advanced alerts
                    if (_state.WeeklyPnL <= -(_advancedConfig.WeeklyLossLimit * 0.8))
                    {
                        alerts.Add(String.Format("Approaching weekly loss limit: {0:C}", _state.WeeklyPnL));
                    }

                    if (_state.TrailingDrawdown >= (_advancedConfig.TrailingDrawdownLimit * 0.8))
                    {
                        alerts.Add(String.Format("High trailing drawdown: {0:C}", _state.TrailingDrawdown));
                    }

                    if (_advancedConfig.MaxCorrelatedExposure.HasValue &&
                        _state.CorrelatedExposure >= (_advancedConfig.MaxCorrelatedExposure.Value * 0.8))
                    {
                        alerts.Add(String.Format("High correlated exposure: {0:C}", _state.CorrelatedExposure));
                    }

                    return new RiskStatus(
                        tradingEnabled: basicStatus.TradingEnabled,
                        dailyPnL: basicStatus.DailyPnL,
                        dailyLossLimit: basicStatus.DailyLossLimit,
                        maxDrawdown: _state.TrailingDrawdown,
                        openPositions: basicStatus.OpenPositions,
                        lastUpdate: _state.LastStateUpdate,
                        activeAlerts: alerts
                    );
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Error getting risk status: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Update correlation matrix for symbols
        /// </summary>
        /// <param name="symbol1">First symbol</param>
        /// <param name="symbol2">Second symbol</param>
        /// <param name="correlation">Correlation coefficient (-1 to 1)</param>
        public void UpdateCorrelation(string symbol1, string symbol2, double correlation)
        {
            if (String.IsNullOrEmpty(symbol1)) throw new ArgumentNullException("symbol1");
            if (String.IsNullOrEmpty(symbol2)) throw new ArgumentNullException("symbol2");
            if (correlation < -1.0 || correlation > 1.0)
                throw new ArgumentException("Correlation must be between -1 and 1", "correlation");

            lock (_lock)
            {
                if (!_correlationMatrix.ContainsKey(symbol1))
                {
                    _correlationMatrix.Add(symbol1, new Dictionary<string, double>());
                }

                if (_correlationMatrix[symbol1].ContainsKey(symbol2))
                {
                    _correlationMatrix[symbol1][symbol2] = correlation;
                }
                else
                {
                    _correlationMatrix[symbol1].Add(symbol2, correlation);
                }

                // Update reverse correlation (symmetric matrix)
                if (!_correlationMatrix.ContainsKey(symbol2))
                {
                    _correlationMatrix.Add(symbol2, new Dictionary<string, double>());
                }

                if (_correlationMatrix[symbol2].ContainsKey(symbol1))
                {
                    _correlationMatrix[symbol2][symbol1] = correlation;
                }
                else
                {
                    _correlationMatrix[symbol2].Add(symbol1, correlation);
                }

                _logger.LogDebug("Updated correlation: {0}-{1} = {2:F3}",
                    symbol1, symbol2, correlation);
            }
        }

        /// <summary>
        /// Update advanced risk configuration
        /// </summary>
        /// <param name="config">New advanced risk configuration</param>
        public void UpdateConfig(AdvancedRiskConfig config)
        {
            if (config == null) throw new ArgumentNullException("config");

            lock (_lock)
            {
                _advancedConfig = config;
                _lastConfigUpdate = DateTime.UtcNow;

                _logger.LogInformation("Advanced risk config updated: WeeklyLimit={0:C}, DrawdownLimit={1:C}",
                    config.WeeklyLossLimit, config.TrailingDrawdownLimit);
            }
        }

        /// <summary>
        /// Reset weekly state - typically called at start of new week
        /// </summary>
        public void ResetWeekly()
        {
            lock (_lock)
            {
                _weekStartDate = GetWeekStart(DateTime.UtcNow);

                _state = new AdvancedRiskState(
                    weeklyPnL: 0,
                    weekStartDate: _weekStartDate,
                    trailingDrawdown: _state.TrailingDrawdown, // Preserve trailing drawdown
                    peakEquity: _state.PeakEquity, // Preserve peak equity
                    activeStrategies: _state.ActiveStrategies,
                    exposureBySymbol: _state.ExposureBySymbol,
                    correlatedExposure: _state.CorrelatedExposure,
                    lastStateUpdate: DateTime.UtcNow
                );

                _logger.LogInformation("Weekly risk state reset: Week start={0}", _weekStartDate);
            }
        }

        /// <summary>
        /// Get current advanced risk state (for testing/monitoring)
        /// </summary>
        public AdvancedRiskState GetAdvancedState()
        {
            lock (_lock)
            {
                return _state;
            }
        }
    }
}
