using System;
using System.Collections.Generic;

namespace NT8.Core.Common.Models
{
    /// <summary>
    /// Risk management configuration
    /// </summary>
    public class RiskConfig
    {
        // Phase 1 - Basic Risk Properties

        /// <summary>
        /// Daily loss limit in dollars
        /// </summary>
        public double DailyLossLimit { get; set; }

        /// <summary>
        /// Maximum risk per trade in dollars
        /// </summary>
        public double MaxTradeRisk { get; set; }

        /// <summary>
        /// Maximum number of open positions
        /// </summary>
        public int MaxOpenPositions { get; set; }

        /// <summary>
        /// Whether emergency flatten is enabled
        /// </summary>
        public bool EmergencyFlattenEnabled { get; set; }

        // Phase 2 - Advanced Risk Properties (Optional)

        /// <summary>
        /// Weekly loss limit in dollars (optional, for advanced risk management)
        /// </summary>
        public double? WeeklyLossLimit { get; set; }

        /// <summary>
        /// Trailing drawdown limit in dollars (optional, for advanced risk management)
        /// </summary>
        public double? TrailingDrawdownLimit { get; set; }

        /// <summary>
        /// Maximum cross-strategy exposure in dollars (optional, for advanced risk management)
        /// </summary>
        public double? MaxCrossStrategyExposure { get; set; }

        /// <summary>
        /// Maximum correlated exposure in dollars (optional, for advanced risk management)
        /// </summary>
        public double? MaxCorrelatedExposure { get; set; }

        /// <summary>
        /// Constructor for RiskConfig (Phase 1 - backward compatible)
        /// </summary>
        public RiskConfig(
            double dailyLossLimit,
            double maxTradeRisk,
            int maxOpenPositions,
            bool emergencyFlattenEnabled)
        {
            DailyLossLimit = dailyLossLimit;
            MaxTradeRisk = maxTradeRisk;
            MaxOpenPositions = maxOpenPositions;
            EmergencyFlattenEnabled = emergencyFlattenEnabled;

            // Phase 2 properties default to null (not set)
            WeeklyLossLimit = null;
            TrailingDrawdownLimit = null;
            MaxCrossStrategyExposure = null;
            MaxCorrelatedExposure = null;
        }

        /// <summary>
        /// Constructor for RiskConfig (Phase 2 - with advanced parameters)
        /// </summary>
        public RiskConfig(
            double dailyLossLimit,
            double maxTradeRisk,
            int maxOpenPositions,
            bool emergencyFlattenEnabled,
            double? weeklyLossLimit,
            double? trailingDrawdownLimit,
            double? maxCrossStrategyExposure,
            double? maxCorrelatedExposure)
        {
            DailyLossLimit = dailyLossLimit;
            MaxTradeRisk = maxTradeRisk;
            MaxOpenPositions = maxOpenPositions;
            EmergencyFlattenEnabled = emergencyFlattenEnabled;
            WeeklyLossLimit = weeklyLossLimit;
            TrailingDrawdownLimit = trailingDrawdownLimit;
            MaxCrossStrategyExposure = maxCrossStrategyExposure;
            MaxCorrelatedExposure = maxCorrelatedExposure;
        }
    }

    /// <summary>
    /// Position sizing configuration
    /// </summary>
    public class SizingConfig
    {
        /// <summary>
        /// Sizing method to use
        /// </summary>
        public SizingMethod Method { get; set; }

        /// <summary>
        /// Minimum number of contracts
        /// </summary>
        public int MinContracts { get; set; }

        /// <summary>
        /// Maximum number of contracts
        /// </summary>
        public int MaxContracts { get; set; }

        /// <summary>
        /// Risk per trade in dollars
        /// </summary>
        public double RiskPerTrade { get; set; }

        /// <summary>
        /// Method-specific parameters
        /// </summary>
        public Dictionary<string, object> MethodParameters { get; set; }

        /// <summary>
        /// Constructor for SizingConfig
        /// </summary>
        public SizingConfig(
            SizingMethod method,
            int minContracts,
            int maxContracts,
            double riskPerTrade,
            Dictionary<string, object> methodParameters)
        {
            Method = method;
            MinContracts = minContracts;
            MaxContracts = maxContracts;
            RiskPerTrade = riskPerTrade;
            MethodParameters = methodParameters ?? new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Strategy configuration
    /// </summary>
    public class StrategyConfig
    {
        /// <summary>
        /// Strategy name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Trading symbol
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Strategy parameters
        /// </summary>
        public Dictionary<string, object> Parameters { get; set; }

        /// <summary>
        /// Risk settings
        /// </summary>
        public RiskConfig RiskSettings { get; set; }

        /// <summary>
        /// Sizing settings
        /// </summary>
        public SizingConfig SizingSettings { get; set; }

        /// <summary>
        /// Constructor for StrategyConfig
        /// </summary>
        public StrategyConfig(
            string name,
            string symbol,
            Dictionary<string, object> parameters,
            RiskConfig riskSettings,
            SizingConfig sizingSettings)
        {
            Name = name;
            Symbol = symbol;
            Parameters = parameters ?? new Dictionary<string, object>();
            RiskSettings = riskSettings;
            SizingSettings = sizingSettings;
        }
    }

    /// <summary>
    /// Position sizing methods
    /// </summary>
    public enum SizingMethod
    {
        /// <summary>
        /// Fixed number of contracts
        /// </summary>
        FixedContracts,

        /// <summary>
        /// Fixed dollar risk amount
        /// </summary>
        FixedDollarRisk,

        /// <summary>
        /// Percentage of equity
        /// </summary>
        PercentOfEquity,

        /// <summary>
        /// Optimal F calculation
        /// </summary>
        OptimalF,

        /// <summary>
        /// Kelly Criterion sizing
        /// </summary>
        KellyCriterion,

        /// <summary>
        /// Volatility-adjusted sizing
        /// </summary>
        VolatilityAdjusted
    }

    /// <summary>
    /// Risk levels
    /// </summary>
    public enum RiskLevel
    {
        /// <summary>
        /// Low risk
        /// </summary>
        Low,

        /// <summary>
        /// Medium risk
        /// </summary>
        Medium,

        /// <summary>
        /// High risk
        /// </summary>
        High,

        /// <summary>
        /// Critical risk
        /// </summary>
        Critical
    }

    /// <summary>
    /// Risk decision result
    /// </summary>
    public class RiskDecision
    {
        /// <summary>
        /// Whether order is allowed
        /// </summary>
        public bool Allow { get; set; }

        /// <summary>
        /// Rejection reason if not allowed
        /// </summary>
        public string RejectReason { get; set; }

        /// <summary>
        /// Modified intent if changes required
        /// </summary>
        public StrategyIntent ModifiedIntent { get; set; }

        /// <summary>
        /// Risk level assessment
        /// </summary>
        public RiskLevel RiskLevel { get; set; }

        /// <summary>
        /// Risk metrics
        /// </summary>
        public Dictionary<string, object> RiskMetrics { get; set; }

        /// <summary>
        /// Constructor for RiskDecision
        /// </summary>
        public RiskDecision(
            bool allow,
            string rejectReason,
            StrategyIntent modifiedIntent,
            RiskLevel riskLevel,
            Dictionary<string, object> riskMetrics)
        {
            Allow = allow;
            RejectReason = rejectReason;
            ModifiedIntent = modifiedIntent;
            RiskLevel = riskLevel;
            RiskMetrics = riskMetrics ?? new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Risk status information
    /// </summary>
    public class RiskStatus
    {
        /// <summary>
        /// Whether trading is enabled
        /// </summary>
        public bool TradingEnabled { get; set; }

        /// <summary>
        /// Daily profit/loss
        /// </summary>
        public double DailyPnL { get; set; }

        /// <summary>
        /// Daily loss limit
        /// </summary>
        public double DailyLossLimit { get; set; }

        /// <summary>
        /// Maximum drawdown
        /// </summary>
        public double MaxDrawdown { get; set; }

        /// <summary>
        /// Number of open positions
        /// </summary>
        public int OpenPositions { get; set; }

        /// <summary>
        /// Last update timestamp
        /// </summary>
        public DateTime LastUpdate { get; set; }

        /// <summary>
        /// Active alerts
        /// </summary>
        public List<string> ActiveAlerts { get; set; }

        /// <summary>
        /// Constructor for RiskStatus
        /// </summary>
        public RiskStatus(
            bool tradingEnabled,
            double dailyPnL,
            double dailyLossLimit,
            double maxDrawdown,
            int openPositions,
            DateTime lastUpdate,
            List<string> activeAlerts)
        {
            TradingEnabled = tradingEnabled;
            DailyPnL = dailyPnL;
            DailyLossLimit = dailyLossLimit;
            MaxDrawdown = maxDrawdown;
            OpenPositions = openPositions;
            LastUpdate = lastUpdate;
            ActiveAlerts = activeAlerts ?? new List<string>();
        }
    }

    /// <summary>
    /// Position sizing result
    /// </summary>
    public class SizingResult
    {
        /// <summary>
        /// Number of contracts
        /// </summary>
        public int Contracts { get; set; }

        /// <summary>
        /// Risk amount in dollars
        /// </summary>
        public double RiskAmount { get; set; }

        /// <summary>
        /// Sizing method used
        /// </summary>
        public SizingMethod Method { get; set; }

        /// <summary>
        /// Calculation details
        /// </summary>
        public Dictionary<string, object> Calculations { get; set; }

        /// <summary>
        /// Constructor for SizingResult
        /// </summary>
        public SizingResult(
            int contracts,
            double riskAmount,
            SizingMethod method,
            Dictionary<string, object> calculations)
        {
            Contracts = contracts;
            RiskAmount = riskAmount;
            Method = method;
            Calculations = calculations ?? new Dictionary<string, object>();
        }
    }

    /// <summary>
    /// Sizing metadata
    /// </summary>
    public class SizingMetadata
    {
        /// <summary>
        /// Sizer name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Sizer description
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Required parameters
        /// </summary>
        public List<string> RequiredParameters { get; set; }

        /// <summary>
        /// Constructor for SizingMetadata
        /// </summary>
        public SizingMetadata(
            string name,
            string description,
            List<string> requiredParameters)
        {
            Name = name;
            Description = description;
            RequiredParameters = requiredParameters ?? new List<string>();
        }
    }

    /// <summary>
    /// Order fill information
    /// </summary>
    public class OrderFill
    {
        /// <summary>
        /// Order ID
        /// </summary>
        public string OrderId { get; set; }

        /// <summary>
        /// Symbol
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Fill quantity
        /// </summary>
        public int Quantity { get; set; }

        /// <summary>
        /// Fill price
        /// </summary>
        public double FillPrice { get; set; }

        /// <summary>
        /// Fill timestamp
        /// </summary>
        public DateTime FillTime { get; set; }

        /// <summary>
        /// Commission paid
        /// </summary>
        public double Commission { get; set; }

        /// <summary>
        /// Execution ID
        /// </summary>
        public string ExecutionId { get; set; }

        /// <summary>
        /// Constructor for OrderFill
        /// </summary>
        public OrderFill(
            string orderId,
            string symbol,
            int quantity,
            double fillPrice,
            DateTime fillTime,
            double commission,
            string executionId)
        {
            OrderId = orderId;
            Symbol = symbol;
            Quantity = quantity;
            FillPrice = fillPrice;
            FillTime = fillTime;
            Commission = commission;
            ExecutionId = executionId;
        }
    }
}
