using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace NT8.Core.OMS
{
    /// <summary>
    /// Basic implementation of the Order Management System with state machine
    /// </summary>
    public class BasicOrderManager : IOrderManager
    {
        private readonly ILogger<BasicOrderManager> _logger;
        private readonly INT8OrderAdapter _nt8Adapter;
        private readonly Dictionary<string, OrderStatus> _activeOrders;
        private readonly Dictionary<string, OrderRequest> _pendingOrders;
        private readonly List<Action<OrderStatus>> _orderCallbacks;
        private readonly object _lock;
        private bool _disposed = false;

        /// <summary>
        /// Constructor for BasicOrderManager
        /// </summary>
        /// <param name="logger">Logger instance</param>
        /// <param name="nt8Adapter">NT8 order adapter instance</param>
        public BasicOrderManager(ILogger<BasicOrderManager> logger, INT8OrderAdapter nt8Adapter)
        {
            if (logger == null)
                throw new ArgumentNullException("logger");
            if (nt8Adapter == null)
                throw new ArgumentNullException("nt8Adapter");

            _logger = logger;
            _nt8Adapter = nt8Adapter;
            _activeOrders = new Dictionary<string, OrderStatus>();
            _pendingOrders = new Dictionary<string, OrderRequest>();
            _orderCallbacks = new List<Action<OrderStatus>>();
            _lock = new object();

            // Register callback to receive order updates from NT8
            _nt8Adapter.RegisterOrderCallback(OnNT8OrderUpdate);

            _logger.LogInformation("BasicOrderManager initialized");
        }

        /// <summary>
        /// Submit new order for execution
        /// </summary>
        public async Task<OrderResult> SubmitOrderAsync(OrderRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            try
            {
                ValidateOrderRequest(request);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Order validation failed: {0}", ex.Message);
                return new OrderResult(false, null, ex.Message, request);
            }

            try
            {
                string orderId = GenerateOrderId(request);

                // Create initial order status
                var orderStatus = new OrderStatus
                {
                    OrderId = orderId,
                    ClientOrderId = request.ClientOrderId,
                    Symbol = request.Symbol,
                    Side = request.Side,
                    Type = request.Type,
                    Quantity = request.Quantity,
                    LimitPrice = request.LimitPrice,
                    StopPrice = request.StopPrice,
                    State = OrderState.Pending,
                    CreatedTime = DateTime.UtcNow,
                    Fills = new List<OrderFill>()
                };

                lock (_lock)
                {
                    _pendingOrders[orderId] = request;
                    _activeOrders[orderId] = orderStatus;
                }

                _logger.LogDebug("Order {0} submitted to NT8 with request {1}", orderId, request.Symbol);

                // Submit to NT8
                bool nt8Result = await _nt8Adapter.SubmitOrderAsync(request);

                if (nt8Result)
                {
                    // Update state to submitted
                    UpdateOrderState(orderId, OrderState.Submitted);

                    _logger.LogInformation("Order {0} submitted successfully to NT8 for symbol {1}",
                        orderId, request.Symbol);

                    return new OrderResult(true, orderId, "Order submitted successfully", request);
                }
                else
                {
                    // Update state to rejected
                    UpdateOrderState(orderId, OrderState.Rejected);

                    _logger.LogWarning("Order {0} submission failed at NT8 level for symbol {1}",
                        orderId, request.Symbol);

                    return new OrderResult(false, orderId, "Order submission failed at NT8 level", request);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to submit order: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Modify existing order
        /// </summary>
        public async Task<bool> ModifyOrderAsync(OrderModification modification)
        {
            if (modification == null)
                throw new ArgumentNullException("modification");

            try
            {
                ValidateOrderModification(modification);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Order modification validation failed: {0}", ex.Message);
                return false;
            }

            try
            {
                // Check if order exists and is in a modifiable state
                OrderStatus orderStatus;
                lock (_lock)
                {
                    if (!_activeOrders.TryGetValue(modification.OrderId, out orderStatus))
                    {
                        _logger.LogWarning("Attempt to modify non-existent order: {0}", modification.OrderId);
                        return false;
                    }

                    // Only allow modifications for certain states
                    if (orderStatus.State != OrderState.Working && orderStatus.State != OrderState.Submitted)
                    {
                        _logger.LogWarning("Cannot modify order {0} in state {1}",
                            modification.OrderId, orderStatus.State);
                        return false;
                    }
                }

                _logger.LogDebug("Modifying order {0}", modification.OrderId);

                // Send modification to NT8
                bool result = await _nt8Adapter.ModifyOrderAsync(modification);

                if (result)
                {
                    _logger.LogInformation("Order {0} modified successfully", modification.OrderId);
                }
                else
                {
                    _logger.LogWarning("Order {0} modification failed", modification.OrderId);
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to modify order {0}: {1}", modification.OrderId, ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Cancel existing order
        /// </summary>
        public async Task<bool> CancelOrderAsync(OrderCancellation cancellation)
        {
            if (cancellation == null)
                throw new ArgumentNullException("cancellation");

            try
            {
                ValidateOrderCancellation(cancellation);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Order cancellation validation failed: {0}", ex.Message);
                return false;
            }

            try
            {
                // Check if order exists and is in a cancellable state
                OrderStatus orderStatus;
                lock (_lock)
                {
                    if (!_activeOrders.TryGetValue(cancellation.OrderId, out orderStatus))
                    {
                        _logger.LogWarning("Attempt to cancel non-existent order: {0}", cancellation.OrderId);
                        return false;
                    }

                    // Only allow cancellation for certain states
                    if (orderStatus.State == OrderState.Filled ||
                        orderStatus.State == OrderState.Cancelled ||
                        orderStatus.State == OrderState.Rejected)
                    {
                        _logger.LogWarning("Cannot cancel order {0} in state {1}",
                            cancellation.OrderId, orderStatus.State);
                        return false;
                    }
                }

                _logger.LogDebug("Cancelling order {0}", cancellation.OrderId);

                // Send cancellation to NT8
                bool result = await _nt8Adapter.CancelOrderAsync(cancellation);

                if (result)
                {
                    _logger.LogInformation("Order {0} cancellation sent successfully to NT8", cancellation.OrderId);
                }
                else
                {
                    _logger.LogWarning("Order {0} cancellation failed at NT8 level", cancellation.OrderId);
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to cancel order {0}: {1}", cancellation.OrderId, ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Get current status of an order
        /// </summary>
        public async Task<OrderStatus> GetOrderStatusAsync(string orderId)
        {
            if (string.IsNullOrEmpty(orderId))
                throw new ArgumentNullException("orderId");

            lock (_lock)
            {
                OrderStatus status;
                _activeOrders.TryGetValue(orderId, out status);
                return status;
            }
        }

        /// <summary>
        /// Get all active orders (working, partially filled, etc.)
        /// </summary>
        public async Task<List<OrderStatus>> GetActiveOrdersAsync()
        {
            lock (_lock)
            {
                return _activeOrders.Values
                    .Where(o => IsOrderActive(o.State))
                    .ToList();
            }
        }

        /// <summary>
        /// Get all orders for a specific symbol
        /// </summary>
        public async Task<List<OrderStatus>> GetOrdersBySymbolAsync(string symbol)
        {
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");

            lock (_lock)
            {
                return _activeOrders.Values
                    .Where(o => string.Equals(o.Symbol, symbol, StringComparison.OrdinalIgnoreCase))
                    .ToList();
            }
        }

        /// <summary>
        /// Flatten all positions for a specific symbol (cancel all working orders)
        /// </summary>
        public async Task<bool> FlattenSymbolAsync(string symbol)
        {
            if (string.IsNullOrEmpty(symbol))
                throw new ArgumentNullException("symbol");

            try
            {
                var ordersToCancel = await GetOrdersBySymbolAsync(symbol);

                var cancellableOrders = ordersToCancel.Where(o =>
                    o.State == OrderState.Working ||
                    o.State == OrderState.Submitted ||
                    o.State == OrderState.PartiallyFilled).ToList();

                bool allSuccess = true;

                foreach (var order in cancellableOrders)
                {
                    var cancellation = new OrderCancellation(order.OrderId, "FlattenSymbol requested");
                    bool result = await CancelOrderAsync(cancellation);

                    if (!result)
                    {
                        allSuccess = false;
                        _logger.LogWarning("Failed to cancel order {0} during FlattenSymbol for {1}",
                            order.OrderId, symbol);
                    }
                }

                if (allSuccess)
                {
                    _logger.LogInformation("Successfully flattened symbol {0}, cancelled {1} orders",
                        symbol, cancellableOrders.Count);
                }
                else
                {
                    _logger.LogWarning("Partial success flattening symbol {0}, failed to cancel some orders", symbol);
                }

                return allSuccess;
            }
            catch (Exception ex)
            {
                _logger.LogError("Error during FlattenSymbol for {0}: {1}", symbol, ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Flatten all positions across all symbols (cancel all working orders)
        /// </summary>
        public async Task<bool> FlattenAllAsync()
        {
            try
            {
                var allOrders = await GetActiveOrdersAsync();

                var cancellableOrders = allOrders.Where(o =>
                    o.State == OrderState.Working ||
                    o.State == OrderState.Submitted ||
                    o.State == OrderState.PartiallyFilled).ToList();

                bool allSuccess = true;

                foreach (var order in cancellableOrders)
                {
                    var cancellation = new OrderCancellation(order.OrderId, "FlattenAll requested");
                    bool result = await CancelOrderAsync(cancellation);

                    if (!result)
                    {
                        allSuccess = false;
                        _logger.LogWarning("Failed to cancel order {0} during FlattenAll", order.OrderId);
                    }
                }

                if (allSuccess)
                {
                    _logger.LogInformation("Successfully flattened all symbols, cancelled {0} orders",
                        cancellableOrders.Count);
                }
                else
                {
                    _logger.LogWarning("Partial success flattening all symbols, failed to cancel some orders");
                }

                return allSuccess;
            }
            catch (Exception ex)
            {
                _logger.LogError("Error during FlattenAll: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Handle partial fill based on configured strategy.
        /// </summary>
        /// <param name="partialFillInfo">Partial fill details.</param>
        /// <param name="config">Partial fill handling configuration.</param>
        /// <returns>Partial fill handling result.</returns>
        public async Task<PartialFillResult> HandlePartialFillAsync(PartialFillInfo partialFillInfo, PartialFillConfig config)
        {
            if (partialFillInfo == null)
                throw new ArgumentNullException("partialFillInfo");
            if (config == null)
                throw new ArgumentNullException("config");

            try
            {
                if (partialFillInfo.IsComplete)
                {
                    return new PartialFillResult(
                        partialFillInfo.OrderId,
                        PartialFillAction.None,
                        "Order is fully filled",
                        true,
                        null);
                }

                switch (config.Strategy)
                {
                    case PartialFillStrategy.AllowAndWait:
                        return new PartialFillResult(
                            partialFillInfo.OrderId,
                            PartialFillAction.Wait,
                            "Waiting for remaining quantity to fill",
                            false,
                            null);

                    case PartialFillStrategy.CancelRemaining:
                        {
                            var cancel = new OrderCancellation(partialFillInfo.OrderId, "Cancel remaining after partial fill");
                            var cancelled = await CancelOrderAsync(cancel);

                            return new PartialFillResult(
                                partialFillInfo.OrderId,
                                PartialFillAction.CancelRemaining,
                                cancelled ? "Remaining quantity cancelled" : "Failed to cancel remaining quantity",
                                cancelled,
                                null);
                        }

                    case PartialFillStrategy.AcceptPartial:
                        {
                            var meetsThreshold = partialFillInfo.FillPercentage >= config.MinimumFillPercentage;
                            return new PartialFillResult(
                                partialFillInfo.OrderId,
                                meetsThreshold ? PartialFillAction.AcceptPartial : PartialFillAction.Wait,
                                meetsThreshold ? "Partial fill accepted" : "Partial fill below acceptance threshold",
                                meetsThreshold,
                                null);
                        }

                    case PartialFillStrategy.AllOrNone:
                        {
                            var cancel = new OrderCancellation(partialFillInfo.OrderId, "All-or-none policy requires full fill");
                            var cancelled = await CancelOrderAsync(cancel);

                            return new PartialFillResult(
                                partialFillInfo.OrderId,
                                PartialFillAction.CancelRemaining,
                                cancelled ? "Order cancelled due to all-or-none policy" : "Failed to cancel all-or-none order",
                                false,
                                null);
                        }

                    default:
                        return new PartialFillResult(
                            partialFillInfo.OrderId,
                            PartialFillAction.None,
                            "No partial fill action taken",
                            false,
                            null);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to handle partial fill for {0}: {1}", partialFillInfo.OrderId, ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Retry an order by submitting a new request using the existing order details.
        /// </summary>
        /// <param name="orderId">Order ID to retry.</param>
        /// <param name="reason">Reason for retry.</param>
        /// <returns>Order result for the retry submission.</returns>
        public async Task<OrderResult> RetryOrderAsync(string orderId, string reason)
        {
            if (string.IsNullOrEmpty(orderId))
                throw new ArgumentNullException("orderId");
            if (string.IsNullOrEmpty(reason))
                throw new ArgumentNullException("reason");

            try
            {
                OrderStatus originalOrder;
                lock (_lock)
                {
                    if (!_activeOrders.TryGetValue(orderId, out originalOrder))
                    {
                        return new OrderResult(false, null, "Original order not found", null);
                    }
                }

                var retryQuantity = originalOrder.RemainingQuantity > 0 ? originalOrder.RemainingQuantity : originalOrder.Quantity;

                var retryRequest = new OrderRequest
                {
                    Symbol = originalOrder.Symbol,
                    Side = originalOrder.Side,
                    Type = originalOrder.Type,
                    Quantity = retryQuantity,
                    LimitPrice = originalOrder.LimitPrice,
                    StopPrice = originalOrder.StopPrice,
                    TimeInForce = TimeInForce.Day,
                    ClientOrderId = string.Format("{0}-RETRY", originalOrder.ClientOrderId)
                };

                _logger.LogInformation("Retrying order {0}: reason={1}, quantity={2}", orderId, reason, retryQuantity);
                return await SubmitOrderAsync(retryRequest);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to retry order {0}: {1}", orderId, ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Reconcile local order state against broker-provided order snapshot.
        /// </summary>
        /// <param name="brokerOrders">Current broker order snapshot.</param>
        /// <returns>List of order IDs requiring manual review.</returns>
        public async Task<List<string>> ReconcileOrdersAsync(List<OrderStatus> brokerOrders)
        {
            if (brokerOrders == null)
                throw new ArgumentNullException("brokerOrders");

            try
            {
                var mismatchedOrderIds = new List<string>();

                lock (_lock)
                {
                    var brokerById = new Dictionary<string, OrderStatus>(StringComparer.OrdinalIgnoreCase);
                    foreach (var brokerOrder in brokerOrders)
                    {
                        if (brokerOrder != null && !string.IsNullOrEmpty(brokerOrder.OrderId))
                        {
                            brokerById[brokerOrder.OrderId] = brokerOrder;
                        }
                    }

                    foreach (var kvp in _activeOrders.ToList())
                    {
                        var localOrder = kvp.Value;
                        OrderStatus brokerOrder;

                        if (!brokerById.TryGetValue(kvp.Key, out brokerOrder))
                        {
                            if (IsOrderActive(localOrder.State))
                            {
                                mismatchedOrderIds.Add(kvp.Key);
                            }
                            continue;
                        }

                        if (localOrder.State != brokerOrder.State ||
                            localOrder.FilledQuantity != brokerOrder.FilledQuantity ||
                            localOrder.AverageFillPrice != brokerOrder.AverageFillPrice)
                        {
                            _activeOrders[kvp.Key] = brokerOrder;
                            mismatchedOrderIds.Add(kvp.Key);
                        }
                    }

                    foreach (var brokerOrder in brokerById.Values)
                    {
                        if (!_activeOrders.ContainsKey(brokerOrder.OrderId))
                        {
                            _activeOrders[brokerOrder.OrderId] = brokerOrder;
                            mismatchedOrderIds.Add(brokerOrder.OrderId);
                        }
                    }
                }

                _logger.LogInformation("Order reconciliation completed. Mismatches found: {0}", mismatchedOrderIds.Count);
                return await Task.FromResult(mismatchedOrderIds);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to reconcile orders: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Submit a limit order for execution
        /// </summary>
        public async Task<OrderResult> SubmitLimitOrderAsync(LimitOrderRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            try
            {
                ValidateOrderRequest(request);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Limit order validation failed: {0}", ex.Message);
                return new OrderResult(false, null, ex.Message, request);
            }

            try
            {
                return await SubmitOrderAsync(request);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to submit limit order: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Submit a stop order for execution
        /// </summary>
        public async Task<OrderResult> SubmitStopOrderAsync(StopOrderRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            try
            {
                ValidateOrderRequest(request);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Stop order validation failed: {0}", ex.Message);
                return new OrderResult(false, null, ex.Message, request);
            }

            try
            {
                return await SubmitOrderAsync(request);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to submit stop order: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Submit a stop-limit order for execution
        /// </summary>
        public async Task<OrderResult> SubmitStopLimitOrderAsync(StopLimitOrderRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            try
            {
                ValidateOrderRequest(request);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("Stop-limit order validation failed: {0}", ex.Message);
                return new OrderResult(false, null, ex.Message, request);
            }

            try
            {
                return await SubmitOrderAsync(request);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to submit stop-limit order: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Submit a market-if-touched order for execution
        /// </summary>
        public async Task<OrderResult> SubmitMITOrderAsync(MITOrderRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            try
            {
                ValidateOrderRequest(request);
            }
            catch (ArgumentException ex)
            {
                _logger.LogError("MIT order validation failed: {0}", ex.Message);
                return new OrderResult(false, null, ex.Message, request);
            }

            try
            {
                return await SubmitOrderAsync(request);
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to submit MIT order: {0}", ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Subscribe to order status updates
        /// </summary>
        public void SubscribeToOrderUpdates(Action<OrderStatus> callback)
        {
            if (callback == null)
                throw new ArgumentNullException("callback");

            lock (_lock)
            {
                _orderCallbacks.Add(callback);
            }
        }

        /// <summary>
        /// Unsubscribe from order status updates
        /// </summary>
        public void UnsubscribeFromOrderUpdates(Action<OrderStatus> callback)
        {
            if (callback == null)
                throw new ArgumentNullException("callback");

            lock (_lock)
            {
                _orderCallbacks.Remove(callback);
            }
        }

        /// <summary>
        /// Process order updates from NT8
        /// </summary>
        private void OnNT8OrderUpdate(OrderStatus updatedStatus)
        {
            try
            {
                OrderStatus existingStatus;
                lock (_lock)
                {
                    if (!_activeOrders.TryGetValue(updatedStatus.OrderId, out existingStatus))
                    {
                        _logger.LogWarning("Received update for unknown order: {0}", updatedStatus.OrderId);
                        return;
                    }

                    // Update the order status
                    _activeOrders[updatedStatus.OrderId] = updatedStatus;

                    // Remove from pending if it was there
                    if (_pendingOrders.ContainsKey(updatedStatus.OrderId))
                    {
                        _pendingOrders.Remove(updatedStatus.OrderId);
                    }
                }

                // Log state changes
                if (existingStatus.State != updatedStatus.State)
                {
                    _logger.LogDebug("Order {0} state changed from {1} to {2}",
                        updatedStatus.OrderId, existingStatus.State, updatedStatus.State);
                }

                // Trigger callbacks outside of lock to prevent deadlocks
                lock (_lock)
                {
                    foreach (var callback in _orderCallbacks.ToList())
                    {
                        try
                        {
                            callback(updatedStatus);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError("Error in order callback: {0}", ex.Message);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Error processing NT8 order update: {0}", ex.Message);
            }
        }

        /// <summary>
        /// Update order state safely
        /// </summary>
        private void UpdateOrderState(string orderId, OrderState newState)
        {
            OrderStatus existingStatus;

            lock (_lock)
            {
                if (!_activeOrders.TryGetValue(orderId, out existingStatus))
                {
                    return;
                }

                // Validate state transition
                if (!IsValidStateTransition(existingStatus.State, newState))
                {
                    _logger.LogWarning("Invalid state transition for order {0}: {1} -> {2}",
                        orderId, existingStatus.State, newState);
                    return;
                }

                // Create updated status
                var updatedStatus = new OrderStatus
                {
                    OrderId = existingStatus.OrderId,
                    ClientOrderId = existingStatus.ClientOrderId,
                    Symbol = existingStatus.Symbol,
                    Side = existingStatus.Side,
                    Type = existingStatus.Type,
                    Quantity = existingStatus.Quantity,
                    FilledQuantity = existingStatus.FilledQuantity,
                    LimitPrice = existingStatus.LimitPrice,
                    StopPrice = existingStatus.StopPrice,
                    State = newState,
                    CreatedTime = existingStatus.CreatedTime,
                    FilledTime = existingStatus.FilledTime,
                    Fills = existingStatus.Fills,
                    AverageFillPrice = existingStatus.AverageFillPrice,
                    FillValue = existingStatus.FillValue
                };

                // Set fill time if transitioning to filled state
                if (newState == OrderState.Filled && existingStatus.State != OrderState.Filled)
                {
                    updatedStatus.FilledTime = DateTime.UtcNow;
                }

                _activeOrders[orderId] = updatedStatus;
            }

            // Trigger callbacks outside of lock to prevent deadlocks
            lock (_lock)
            {
                foreach (var callback in _orderCallbacks.ToList())
                {
                    try
                    {
                        callback(_activeOrders[orderId]);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError("Error in order callback: {0}", ex.Message);
                    }
                }
            }
        }

        /// <summary>
        /// Validate order request
        /// </summary>
        private void ValidateOrderRequest(OrderRequest request)
        {
            if (string.IsNullOrEmpty(request.Symbol))
                throw new ArgumentException("Symbol is required", "request.Symbol");

            if (request.Quantity <= 0)
                throw new ArgumentException("Quantity must be greater than 0", "request.Quantity");

            if (request.LimitPrice.HasValue && request.LimitPrice <= 0)
                throw new ArgumentException("Limit price must be greater than 0", "request.LimitPrice");

            if (request.StopPrice.HasValue && request.StopPrice <= 0)
                throw new ArgumentException("Stop price must be greater than 0", "request.StopPrice");
        }

        /// <summary>
        /// Validate order modification
        /// </summary>
        private void ValidateOrderModification(OrderModification modification)
        {
            if (string.IsNullOrEmpty(modification.OrderId))
                throw new ArgumentException("Order ID is required", "modification.OrderId");

            if (!modification.NewQuantity.HasValue &&
                !modification.NewLimitPrice.HasValue &&
                !modification.NewStopPrice.HasValue &&
                !modification.NewTimeInForce.HasValue)
            {
                throw new ArgumentException("At least one modification parameter must be specified");
            }

            if (modification.NewQuantity.HasValue && modification.NewQuantity <= 0)
                throw new ArgumentException("New quantity must be greater than 0", "modification.NewQuantity");

            if (modification.NewLimitPrice.HasValue && modification.NewLimitPrice <= 0)
                throw new ArgumentException("New limit price must be greater than 0", "modification.NewLimitPrice");

            if (modification.NewStopPrice.HasValue && modification.NewStopPrice <= 0)
                throw new ArgumentException("New stop price must be greater than 0", "modification.NewStopPrice");
        }

        /// <summary>
        /// Validate order cancellation
        /// </summary>
        private void ValidateOrderCancellation(OrderCancellation cancellation)
        {
            if (string.IsNullOrEmpty(cancellation.OrderId))
                throw new ArgumentException("Order ID is required", "cancellation.OrderId");
        }

        /// <summary>
        /// Generate unique order ID
        /// </summary>
        private string GenerateOrderId(OrderRequest request)
        {
            string guidString = Guid.NewGuid().ToString("N");
            string shortGuid = guidString.Substring(0, Math.Min(8, guidString.Length)).ToUpper();
            return string.Format("OMS-{0}-{1}",
                request.Symbol.Replace(".", ""),
                shortGuid);
        }

        /// <summary>
        /// Check if state transition is valid
        /// </summary>
        private bool IsValidStateTransition(OrderState currentState, OrderState newState)
        {
            // Define valid state transitions
            switch (currentState)
            {
                case OrderState.Pending:
                    return newState == OrderState.Submitted ||
                           newState == OrderState.Rejected;

                case OrderState.Submitted:
                    return newState == OrderState.Accepted ||
                           newState == OrderState.Rejected ||
                           newState == OrderState.Cancelled;

                case OrderState.Accepted:
                    return newState == OrderState.Working ||
                           newState == OrderState.Cancelled ||
                           newState == OrderState.Rejected;

                case OrderState.Working:
                    return newState == OrderState.PartiallyFilled ||
                           newState == OrderState.Filled ||
                           newState == OrderState.Cancelled ||
                           newState == OrderState.Expired;

                case OrderState.PartiallyFilled:
                    return newState == OrderState.Filled ||
                           newState == OrderState.Cancelled ||
                           newState == OrderState.Expired;

                case OrderState.Filled:
                case OrderState.Cancelled:
                case OrderState.Rejected:
                case OrderState.Expired:
                    // Terminal states - no further transitions allowed
                    return false;

                default:
                    return false;
            }
        }

        /// <summary>
        /// Check if order is in active state
        /// </summary>
        private bool IsOrderActive(OrderState state)
        {
            return state == OrderState.Pending ||
                   state == OrderState.Submitted ||
                   state == OrderState.Accepted ||
                   state == OrderState.Working ||
                   state == OrderState.PartiallyFilled;
        }

        /// <summary>
        /// Dispose resources
        /// </summary>
        public void Dispose()
        {
            if (!_disposed)
            {
                _nt8Adapter.UnregisterOrderCallback(OnNT8OrderUpdate);
                _disposed = true;
            }
        }
    }
}
