using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Utils.CoordinateSystem;

namespace NavisworksTransport.UnitTests.CoordinateSystem
{
    [TestClass]
    public class ObjectSpaceOrientationHelperTests
    {
        [TestMethod]
        public void CalculateAxes_ShouldHonorProvidedUpReference()
        {
            var segmentDirection = new Vector3(10f, 0f, 0f);
            var upReference = new Vector3(0f, 1f, 0f);

            var (_, up) = ObjectSpaceOrientationHelper.CalculateAxes(segmentDirection, upReference);

            Assert.AreEqual(0.0, up.X, 1e-6);
            Assert.AreEqual(1.0, System.Math.Abs(up.Y), 1e-6);
            Assert.AreEqual(0.0, up.Z, 1e-6);
        }

        [TestMethod]
        public void CalculateAxes_ForVerticalSegment_ShouldUseHorizontalDirectionWithProvidedUpReference()
        {
            var segmentDirection = new Vector3(0f, 10f, 0f);
            var upReference = new Vector3(0f, 1f, 0f);
            var horizontalDirection = new Vector3(1f, 0f, 0f);

            var (right, up) = ObjectSpaceOrientationHelper.CalculateAxes(segmentDirection, upReference, horizontalDirection);

            Assert.AreEqual(0.0, right.X, 1e-6);
            Assert.AreEqual(0.0, right.Y, 1e-6);
            Assert.AreEqual(1.0, right.Z, 1e-6);
            Assert.AreEqual(1.0, up.X, 1e-6);
            Assert.AreEqual(0.0, up.Y, 1e-6);
            Assert.AreEqual(0.0, up.Z, 1e-6);
        }

        [TestMethod]
        public void TryCalculateAxes_ShouldReturnFalse_ForZeroLengthSegment()
        {
            var segmentDirection = Vector3.Zero;
            var upReference = new Vector3(0f, 1f, 0f);

            bool ok = ObjectSpaceOrientationHelper.TryCalculateAxes(
                segmentDirection,
                upReference,
                out var axes);

            Assert.IsFalse(ok);
            Assert.AreEqual(Vector3.Zero, axes.right);
            Assert.AreEqual(Vector3.Zero, axes.up);
        }
    }
}
