using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NT8.Core.OMS;

namespace NT8.Core.Tests.Mocks
{
    /// <summary>
    /// Mock implementation of INT8OrderAdapter for testing purposes
    /// </summary>
    public class MockNT8OrderAdapter : INT8OrderAdapter
    {
        private readonly List<Action<OrderStatus>> _callbacks;
        private readonly object _lock;
        private bool _disposed = false;
        private bool _isConnected = false;
        private bool _shouldSucceed = true;
        private bool _shouldFail = false;
        private int _submitOrderCallCount = 0;
        private int _modifyOrderCallCount = 0;
        private int _cancelOrderCallCount = 0;

        /// <summary>
        /// Gets or sets whether the next operation should succeed
        /// </summary>
        public bool ShouldSucceed
        {
            get { return _shouldSucceed; }
            set { _shouldSucceed = value; }
        }

        /// <summary>
        /// Gets or sets whether the next operation should fail
        /// </summary>
        public bool ShouldFail
        {
            get { return _shouldFail; }
            set { _shouldFail = value; }
        }

        /// <summary>
        /// Gets the count of submitted orders
        /// </summary>
        public int SubmitOrderCallCount
        {
            get { return _submitOrderCallCount; }
            private set { _submitOrderCallCount = value; }
        }

        /// <summary>
        /// Gets the count of modified orders
        /// </summary>
        public int ModifyOrderCallCount
        {
            get { return _modifyOrderCallCount; }
            private set { _modifyOrderCallCount = value; }
        }

        /// <summary>
        /// Gets the count of cancelled orders
        /// </summary>
        public int CancelOrderCallCount
        {
            get { return _cancelOrderCallCount; }
            private set { _cancelOrderCallCount = value; }
        }

        /// <summary>
        /// Constructor for MockNT8OrderAdapter
        /// </summary>
        public MockNT8OrderAdapter()
        {
            _callbacks = new List<Action<OrderStatus>>();
            _lock = new object();
        }

        /// <summary>
        /// Submit order to NinjaTrader 8 (mock implementation)
        /// </summary>
        public async Task<bool> SubmitOrderAsync(OrderRequest request)
        {
            SubmitOrderCallCount++;

            if (ShouldFail)
            {
                return false;
            }

            // Simulate successful submission
            return ShouldSucceed;
        }

        /// <summary>
        /// Modify existing order in NinjaTrader 8 (mock implementation)
        /// </summary>
        public async Task<bool> ModifyOrderAsync(OrderModification modification)
        {
            ModifyOrderCallCount++;

            if (ShouldFail)
            {
                return false;
            }

            // Simulate successful modification
            return ShouldSucceed;
        }

        /// <summary>
        /// Cancel order in NinjaTrader 8 (mock implementation)
        /// </summary>
        public async Task<bool> CancelOrderAsync(OrderCancellation cancellation)
        {
            CancelOrderCallCount++;

            if (ShouldFail)
            {
                return false;
            }

            // Simulate successful cancellation
            return ShouldSucceed;
        }

        /// <summary>
        /// Register callback for order status updates (mock implementation)
        /// </summary>
        public void RegisterOrderCallback(Action<OrderStatus> callback)
        {
            if (callback == null)
                throw new ArgumentNullException("callback");

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

        /// <summary>
        /// Unregister callback for order status updates (mock implementation)
        /// </summary>
        public void UnregisterOrderCallback(Action<OrderStatus> callback)
        {
            if (callback == null)
                throw new ArgumentNullException("callback");

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

        /// <summary>
        /// Connect to NinjaTrader 8 (mock implementation)
        /// </summary>
        public async Task<bool> ConnectAsync()
        {
            if (ShouldFail)
            {
                return false;
            }

            _isConnected = true;
            return ShouldSucceed;
        }

        /// <summary>
        /// Disconnect from NinjaTrader 8 (mock implementation)
        /// </summary>
        public async Task<bool> DisconnectAsync()
        {
            _isConnected = false;
            return true;
        }

        /// <summary>
        /// Fire an order status update to all registered callbacks
        /// </summary>
        /// <param name="status">The order status to fire</param>
        public void FireOrderUpdate(OrderStatus status)
        {
            lock (_lock)
            {
                foreach (var callback in _callbacks)
                {
                    try
                    {
                        callback(status);
                    }
                    catch
                    {
                        // Ignore exceptions in callbacks for this mock
                    }
                }
            }
        }

        /// <summary>
        /// Gets whether the adapter is currently connected
        /// </summary>
        public bool IsConnected
        {
            get
            {
                return _isConnected;
            }
        }

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