using System;

namespace NT8.Core.Execution
{
    /// <summary>
    /// Decision result for order routing
    /// </summary>
    public class RoutingDecision
    {
        /// <summary>
        /// Order ID being routed
        /// </summary>
        public string OrderId { get; set; }

        /// <summary>
        /// Venue to route the order to
        /// </summary>
        public string RoutingVenue { get; set; }

        /// <summary>
        /// Routing strategy used
        /// </summary>
        public RoutingStrategy Strategy { get; set; }

        /// <summary>
        /// Confidence level in the routing decision (0-100)
        /// </summary>
        public int Confidence { get; set; }

        /// <summary>
        /// Expected execution quality
        /// </summary>
        public ExecutionQuality ExpectedQuality { get; set; }

        /// <summary>
        /// Expected latency in milliseconds
        /// </summary>
        public int ExpectedLatencyMs { get; set; }

        /// <summary>
        /// Whether the routing decision is valid
        /// </summary>
        public bool IsValid { get; set; }

        /// <summary>
        /// Reason for the routing decision
        /// </summary>
        public string Reason { get; set; }

        /// <summary>
        /// Constructor for RoutingDecision
        /// </summary>
        /// <param name="orderId">Order ID</param>
        /// <param name="routingVenue">Venue to route to</param>
        /// <param name="strategy">Routing strategy</param>
        /// <param name="confidence">Confidence level</param>
        /// <param name="expectedQuality">Expected quality</param>
        /// <param name="expectedLatencyMs">Expected latency in ms</param>
        /// <param name="isValid">Whether decision is valid</param>
        /// <param name="reason">Reason for decision</param>
        public RoutingDecision(
            string orderId,
            string routingVenue,
            RoutingStrategy strategy,
            int confidence,
            ExecutionQuality expectedQuality,
            int expectedLatencyMs,
            bool isValid,
            string reason)
        {
            if (string.IsNullOrEmpty(orderId))
                throw new ArgumentNullException("orderId");

            OrderId = orderId;
            RoutingVenue = routingVenue;
            Strategy = strategy;
            Confidence = confidence;
            ExpectedQuality = expectedQuality;
            ExpectedLatencyMs = expectedLatencyMs;
            IsValid = isValid;
            Reason = reason;
        }
    }

    /// <summary>
    /// Information for checking duplicate orders
    /// </summary>
    public class OrderDuplicateCheck
    {
        /// <summary>
        /// Order ID to check
        /// </summary>
        public string OrderId { get; set; }

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

        /// <summary>
        /// Side of the order
        /// </summary>
        public OMS.OrderSide Side { get; set; }

        /// <summary>
        /// Quantity of the order
        /// </summary>
        public int Quantity { get; set; }

        /// <summary>
        /// Time when the order intent was created
        /// </summary>
        public DateTime IntentTime { get; set; }

        /// <summary>
        /// Whether this is a duplicate order
        /// </summary>
        public bool IsDuplicate { get; set; }

        /// <summary>
        /// Time window for duplicate checking
        /// </summary>
        public TimeSpan DuplicateWindow { get; set; }

        /// <summary>
        /// Constructor for OrderDuplicateCheck
        /// </summary>
        /// <param name="orderId">Order ID</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="side">Order side</param>
        /// <param name="quantity">Quantity</param>
        /// <param name="intentTime">Intent time</param>
        /// <param name="duplicateWindow">Duplicate window</param>
        public OrderDuplicateCheck(
            string orderId,
            string symbol,
            OMS.OrderSide side,
            int quantity,
            DateTime intentTime,
            TimeSpan duplicateWindow)
        {
            if (string.IsNullOrEmpty(orderId))
                throw new ArgumentNullException("orderId");
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");

            OrderId = orderId;
            Symbol = symbol;
            Side = side;
            Quantity = quantity;
            IntentTime = intentTime;
            DuplicateWindow = duplicateWindow;
        }
    }

    /// <summary>
    /// Current state of circuit breaker
    /// </summary>
    public class CircuitBreakerState
    {
        /// <summary>
        /// Whether the circuit breaker is active
        /// </summary>
        public bool IsActive { get; set; }

        /// <summary>
        /// Current state of the circuit breaker
        /// </summary>
        public CircuitBreakerStatus Status { get; set; }

        /// <summary>
        /// Reason for the current state
        /// </summary>
        public string Reason { get; set; }

        /// <summary>
        /// Time when the state was last updated
        /// </summary>
        public DateTime LastUpdateTime { get; set; }

        /// <summary>
        /// Time when the circuit breaker will reset (if applicable)
        /// </summary>
        public DateTime? ResetTime { get; set; }

        /// <summary>
        /// Number of violations that triggered the state
        /// </summary>
        public int ViolationCount { get; set; }

        /// <summary>
        /// Constructor for CircuitBreakerState
        /// </summary>
        /// <param name="isActive">Whether active</param>
        /// <param name="status">Current status</param>
        /// <param name="reason">Reason for state</param>
        /// <param name="violationCount">Violation count</param>
        public CircuitBreakerState(
            bool isActive,
            CircuitBreakerStatus status,
            string reason,
            int violationCount)
        {
            IsActive = isActive;
            Status = status;
            Reason = reason;
            ViolationCount = violationCount;
            LastUpdateTime = DateTime.UtcNow;
        }
    }

    /// <summary>
    /// Routing strategy enumeration
    /// </summary>
    public enum RoutingStrategy
    {
        /// <summary>
        /// Direct routing to primary venue
        /// </summary>
        Direct = 0,

        /// <summary>
        /// Smart routing based on market conditions
        /// </summary>
        Smart = 1,

        /// <summary>
        /// Fallback to alternative venue
        /// </summary>
        Fallback = 2
    }

    /// <summary>
    /// Circuit breaker status enumeration
    /// </summary>
    public enum CircuitBreakerStatus
    {
        /// <summary>
        /// Normal operation
        /// </summary>
        Closed = 0,

        /// <summary>
        /// Circuit breaker activated
        /// </summary>
        Open = 1,

        /// <summary>
        /// Testing if conditions have improved
        /// </summary>
        HalfOpen = 2
    }
}
