using System.Collections.Generic;
using System.Web.Http;
using CncModels.Dto.Common;
using CncModels.Dto.Screen;
using CncWebApi.Controllers;
using Xunit;

namespace CncWebApi.Tests
{
    /// <summary>
    /// ScreenController单元测试
    /// 大屏看板接口（无需认证）
    /// </summary>
    [Collection("Database")]
    public class ScreenControllerTests
    {
        private readonly ScreenController _controller;

        public ScreenControllerTests()
        {
            TestDb.TruncateAll();
            _controller = ControllerFactory.CreateScreenController();
        }

        /// <summary>
        /// 辅助：从ApiResponse&lt;object&gt;中获取interval值
        /// Controller返回 Ok(ApiResponse&lt;object&gt;.Success(new { interval }))
        /// </summary>
        private static int GetIntervalFromResult(IHttpActionResult result)
        {
            // 先获取Content（ApiResponse<object>）
            var content = result.GetType().GetProperty("Content")?.GetValue(result);
            Assert.NotNull(content);
            // 再获取Data属性（匿名类型 { interval }）
            var data = content.GetType().GetProperty("Data")?.GetValue(content);
            Assert.NotNull(data);
            var intervalProp = data.GetType().GetProperty("interval");
            Assert.NotNull(intervalProp);
            return (int)intervalProp.GetValue(data);
        }

        #region GetSummary - 大屏汇总

        /// <summary>
        /// 测试：空数据库也返回汇总数据
        /// </summary>
        [Fact]
        public void GetSummary_EmptyDb_ShouldReturnData()
        {
            var result = _controller.GetSummary();
            var response = ControllerFactory.Extract<ScreenSummaryResponse>(result);
            ControllerFactory.AssertSuccess(response);
            Assert.NotNull(response.Data);
        }

        #endregion

        #region GetCollectorStatus - 采集服务状态

        [Fact]
        public void GetCollectorStatus_ShouldReturnData()
        {
            var result = _controller.GetCollectorStatus();
            Assert.NotNull(result);
            var content = result.GetType().GetProperty("Content")?.GetValue(result);
            Assert.NotNull(content);
        }

        #endregion

        #region GetWorkshopProduction - 各车间产量

        [Fact]
        public void GetWorkshopProduction_ShouldReturnList()
        {
            var result = _controller.GetWorkshopProduction();
            Assert.NotNull(result);
        }

        #endregion

        #region GetProductionTrend - 产量趋势

        [Fact]
        public void GetProductionTrend_ShouldReturnData()
        {
            var result = _controller.GetProductionTrend(7);
            Assert.NotNull(result);
            var content = result.GetType().GetProperty("Content")?.GetValue(result);
            Assert.NotNull(content);
        }

        #endregion

        #region GetMachineRank - 机床排行

        [Fact]
        public void GetMachineRank_ShouldReturnList()
        {
            var result = _controller.GetMachineRank(10);
            Assert.NotNull(result);
        }

        #endregion

        #region GetWorkerRank - 工人排行

        [Fact]
        public void GetWorkerRank_ShouldReturnList()
        {
            var result = _controller.GetWorkerRank(10);
            Assert.NotNull(result);
        }

        #endregion

        #region GetMachineStatus - 机床状态

        [Fact]
        public void GetMachineStatus_ShouldReturnData()
        {
            var result = _controller.GetMachineStatus();
            Assert.NotNull(result);
        }

        #endregion

        #region GetFilters - 大屏筛选条件

        /// <summary>
        /// 测试：无筛选配置返回空列表
        /// </summary>
        [Fact]
        public void GetFilters_NoData_ShouldReturnEmpty()
        {
            var result = _controller.GetFilters("main_screen");
            var response = ControllerFactory.Extract<List<SimpleOption>>(result);
            ControllerFactory.AssertSuccess(response);
            Assert.NotNull(response.Data);
        }

        /// <summary>
        /// 测试：有筛选配置时返回选项列表
        /// </summary>
        [Fact]
        public void GetFilters_WithData_ShouldReturnOptions()
        {
            TestDb.Execute(@"INSERT INTO cnc_screen_filter (screen_key, filter_type, filter_value, is_default, sort_order)
                VALUES ('main_screen', 'workshop', 'A栋', 0, 1)");

            var result = _controller.GetFilters("main_screen");
            var response = ControllerFactory.Extract<List<SimpleOption>>(result);
            Assert.NotEmpty(response.Data);
        }

        #endregion

        #region GetRefreshInterval - 刷新间隔

        /// <summary>
        /// 测试：无配置时默认30秒
        /// </summary>
        [Fact]
        public void GetRefreshInterval_NoConfig_ShouldReturnDefault30()
        {
            var result = _controller.GetRefreshInterval();
            Assert.Equal(30, GetIntervalFromResult(result));
        }

        /// <summary>
        /// 测试：有配置时返回配置值
        /// </summary>
        [Fact]
        public void GetRefreshInterval_WithConfig_ShouldReturnConfiguredValue()
        {
            TestDb.Execute(@"INSERT INTO cnc_sys_config (config_key, config_value, value_type, description, updated_at)
                VALUES ('screen_refresh_interval', '60', 'int', '大屏刷新间隔', NOW())");

            var controller = ControllerFactory.CreateScreenController();
            var result = controller.GetRefreshInterval();
            Assert.Equal(60, GetIntervalFromResult(result));
        }

        #endregion
    }
}
