using Microsoft.VisualStudio.TestTools.UnitTesting;
using NT8.Core.OMS;

namespace NT8.Core.Tests.OMS
{
    [TestClass]
    public class OrderStateMachineTests
    {
        private OrderStateMachine _stateMachine;

        [TestInitialize]
        public void TestInitialize()
        {
            _stateMachine = new OrderStateMachine();
        }

        [TestMethod]
        public void ValidateTransition_PendingToSubmitted_ShouldBeValid()
        {
            var result = _stateMachine.ValidateTransition("ORD-1", OrderState.Pending, OrderState.Submitted);

            Assert.IsTrue(result.IsValid);
        }

        [TestMethod]
        public void ValidateTransition_SubmittedToFilled_ShouldBeInvalid()
        {
            var result = _stateMachine.ValidateTransition("ORD-1", OrderState.Submitted, OrderState.Filled);

            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public void ValidateTransition_SameState_ShouldBeValidIdempotent()
        {
            var result = _stateMachine.ValidateTransition("ORD-1", OrderState.Working, OrderState.Working);

            Assert.IsTrue(result.IsValid);
        }

        [TestMethod]
        public void IsTerminalState_Filled_ShouldReturnTrue()
        {
            Assert.IsTrue(_stateMachine.IsTerminalState(OrderState.Filled));
            Assert.IsTrue(_stateMachine.IsTerminalState(OrderState.Cancelled));
            Assert.IsTrue(_stateMachine.IsTerminalState(OrderState.Rejected));
            Assert.IsTrue(_stateMachine.IsTerminalState(OrderState.Expired));
        }

        [TestMethod]
        public void IsTerminalState_Working_ShouldReturnFalse()
        {
            Assert.IsFalse(_stateMachine.IsTerminalState(OrderState.Working));
        }

        [TestMethod]
        public void RecordTransition_ThenGetHistory_ShouldContainEntry()
        {
            _stateMachine.RecordTransition("ORD-ABC", OrderState.Pending, OrderState.Submitted, "Submitted to broker");
            var history = _stateMachine.GetOrderHistory("ORD-ABC");

            Assert.AreEqual(1, history.Count);
            Assert.AreEqual(OrderState.Pending, history[0].FromState);
            Assert.AreEqual(OrderState.Submitted, history[0].ToState);
        }

        [TestMethod]
        public void GetAllowedNextStates_Working_ShouldContainExpectedStates()
        {
            var next = _stateMachine.GetAllowedNextStates(OrderState.Working);

            Assert.IsTrue(next.Contains(OrderState.PartiallyFilled));
            Assert.IsTrue(next.Contains(OrderState.Filled));
            Assert.IsTrue(next.Contains(OrderState.Cancelled));
            Assert.IsTrue(next.Contains(OrderState.Expired));
        }

        [TestMethod]
        public void ClearHistory_AfterRecording_ShouldRemoveEntries()
        {
            _stateMachine.RecordTransition("ORD-XYZ", OrderState.Pending, OrderState.Submitted, "test");
            _stateMachine.ClearHistory();

            var history = _stateMachine.GetOrderHistory("ORD-XYZ");
            Assert.AreEqual(0, history.Count);
        }
    }
}
