using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;

namespace NavisworksTransport.UnitTests.Integration
{
    [TestClass]
    [TestCategory("NavisworksIntegration")]
    public class VirtualCollisionAutomationTests
    {
        private const int DefaultCollisionTimeoutSeconds = 240;
        private const int TestFrameRate = 15;
        private const double TestDurationSeconds = 5.0;

        [TestMethod]
        [Timeout(360000)]
        public async Task GroundVirtualCollision_AutoTestRoute_Completes()
        {
            await AssertVirtualCollisionTestAsync("Ground").ConfigureAwait(false);
        }

        [TestMethod]
        [Timeout(360000)]
        public async Task HoistingVirtualCollision_AutoTestRoute_Completes()
        {
            await AssertVirtualCollisionTestAsync("Hoisting").ConfigureAwait(false);
        }

        [TestMethod]
        [Timeout(360000)]
        public async Task RailVirtualCollision_AutoTestRoute_Completes()
        {
            await AssertVirtualCollisionTestAsync("Rail").ConfigureAwait(false);
        }

        private static async Task AssertVirtualCollisionTestAsync(string pathType)
        {
            using (var client = new NavisworksTestAutomationClient())
            {
                await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);

                JObject response = await client.RunCollisionTestAsync(
                    pathType,
                    DefaultCollisionTimeoutSeconds,
                    frameRate: TestFrameRate,
                    durationSeconds: TestDurationSeconds).ConfigureAwait(false);
                Assert.IsTrue(response.Value<bool>("ok"), "测试 HTTP 接口返回失败: " + (string)response["error"]);

                JObject data = (JObject)response["data"];
                Assert.IsNotNull(data, "缺少测试结果 data");

                Assert.AreEqual(pathType, (string)data["requestedPathType"], "请求的路径类型不匹配");

                JObject route = (JObject)data["route"];
                Assert.IsNotNull(route, "缺少 route");
                Assert.AreEqual(pathType, (string)route["pathType"], "返回的路径类型不匹配");
                Assert.IsFalse(string.IsNullOrWhiteSpace((string)route["name"]), "路径名为空");

                JObject animatedObject = (JObject)data["animatedObject"];
                Assert.IsNotNull(animatedObject, "缺少 animatedObject");
                Assert.AreEqual("VirtualObject", (string)animatedObject["mode"], "当前集成测试应使用虚拟物体");

                JObject animation = (JObject)data["animation"];
                Assert.IsNotNull(animation, "缺少 animation");
                Assert.AreEqual("Finished", (string)animation["currentState"], "动画未完成");
                Assert.IsTrue((int)animation["totalFrames"] > 0, "动画总帧数应大于 0");
                Assert.IsTrue(animation["detectionRecordId"] != null && (int)animation["detectionRecordId"] > 0, "检测记录 ID 无效");

                CollisionReportAssertions.AssertReportStructure(data, route);
            }
        }
    }
}
