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

namespace NavisworksTransport.UnitTests.Integration
{
    /// <summary>
    /// 批处理队列 F1 端到端测试（剖面盒自动检测，副实例多进程）。
    ///
    /// 独立 TestCategory（NavisworksIntegrationF1），不进默认全量
    /// （TestCategory=NavisworksIntegration），因为完整 F1 流程
    /// （副实例启动 + 剖面盒导出 + 局部模型检测）耗时较长（分钟级）。
    ///
    /// 单独运行：
    ///   run-integration-tests.bat "TestCategory=NavisworksIntegrationF1"
    ///
    /// 覆盖链路：add（虚拟物体，DetectAllObjects=true）→ process（触发 F1）
    /// → 轮询 batch-queue-status 至 Completed → 断言碰撞报告已生成。
    /// </summary>
    [TestClass]
    [TestCategory("NavisworksIntegrationF1")]
    public class BatchQueueF1ProcessAutomationTests
    {
        private const int TestFrameRate = 15;
        private const double TestDurationSeconds = 5.0;

        [TestMethod]
        [Timeout(360000)]
        public async Task BatchQueueF1_ProcessQueue_CompletesWithCollisionReport()
        {
            using (var client = new NavisworksTestAutomationClient())
            {
                await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);

                // 1. 添加虚拟物体队列项（F1 剖面盒自动检测：DetectAllObjects=true 走副实例）
                JObject add = await client.BatchQueueAddAsync(
                    "自动测试_Ground", TestFrameRate, TestDurationSeconds).ConfigureAwait(false);
                Assert.IsTrue(add.Value<bool>("ok"), "添加队列项失败: " + (string)add["error"]);

                int itemId = (int)((JObject)add["data"])["itemId"];
                Assert.IsTrue(itemId > 0, "队列项 ID 无效");

                // 2. 触发后台处理（F1）
                JObject process = await client.BatchQueueProcessAsync().ConfigureAwait(false);
                Assert.IsTrue(process.Value<bool>("ok"), "触发批处理失败: " + (string)process["error"]);

                // 3. 轮询队列状态直到该 itemId 进入终态（Completed/Failed）
                DateTime deadline = DateTime.UtcNow.AddMinutes(3);
                string status = null;
                string errorMessage = null;
                while (DateTime.UtcNow < deadline)
                {
                    await Task.Delay(5000).ConfigureAwait(false);

                    JObject statusResp = await client.BatchQueueStatusAsync(10).ConfigureAwait(false);
                    Assert.IsTrue(statusResp.Value<bool>("ok"), "查询队列状态失败");

                    var items = (JArray)statusResp["data"]["items"];
                    var mine = items?.FirstOrDefault(i => (int)i["itemId"] == itemId);
                    if (mine != null)
                    {
                        status = (string)mine["status"];
                        errorMessage = (string)mine["errorMessage"];
                        if (status == "Completed" || status == "Failed")
                        {
                            break;
                        }
                    }
                }

                Assert.AreEqual(
                    "Completed",
                    status,
                    "F1 批处理未在时限内完成。itemId=" + itemId +
                    (string.IsNullOrEmpty(errorMessage) ? "" : "，错误: " + errorMessage));

                // 等待后台批处理完全退出（避免后台任务残留影响后续测试的 isExecuting 断言）
                DateTime exitDeadline = DateTime.UtcNow.AddSeconds(90);
                while (DateTime.UtcNow < exitDeadline)
                {
                    JObject statusResp = await client.BatchQueueStatusAsync(1).ConfigureAwait(false);
                    bool isExecuting = (bool?)statusResp["data"]?["isExecuting"] ?? false;
                    if (!isExecuting)
                    {
                        break;
                    }
                    await Task.Delay(2000).ConfigureAwait(false);
                }
            }
        }
    }
}
