using System.Collections.Generic;
using CncModels.Dto;
using CncModels.Dto.CollectAddress;
using CncService;
using CncWebApi.Controllers;
using Xunit;

namespace CncWebApi.Tests
{
    /// <summary>
    /// CollectAddressController单元测试
    /// 采集地址CRUD + 启停
    /// </summary>
    [Collection("Database")]
    public class CollectAddressControllerTests
    {
        private readonly CollectAddressController _controller;

        public CollectAddressControllerTests()
        {
            TestDb.TruncateAll();
            _controller = ControllerFactory.CreateCollectAddressController();
        }

        /// <summary>
        /// 辅助：创建地址请求
        /// </summary>
        private CreateCollectAddressRequest CreateRequest(string name = "地址1", string url = "http://192.168.1.1") => new CreateCollectAddressRequest
        {
            Name = name,
            Url = url,
            BrandId = 1,
            CollectInterval = 5
        };

        #region GetList - 地址列表

        /// <summary>
        /// 测试：空数据库返回空列表
        /// </summary>
        [Fact]
        public void GetList_EmptyDb_ShouldReturnEmpty()
        {
            var result = _controller.GetList(new CollectAddressQuery());
            var response = ControllerFactory.Extract<PagedResult<CollectAddressListItem>>(result);
            ControllerFactory.AssertSuccess(response);
            Assert.Empty(response.Data.Items);
        }

        /// <summary>
        /// 测试：新增后列表有数据
        /// </summary>
        [Fact]
        public void GetList_AfterCreate_ShouldReturnOne()
        {
            _controller.Create(CreateRequest());
            var result = _controller.GetList(new CollectAddressQuery());
            var response = ControllerFactory.Extract<PagedResult<CollectAddressListItem>>(result);
            Assert.Single(response.Data.Items);
        }

        #endregion

        #region GetById - 地址详情

        /// <summary>
        /// 测试：获取地址详情成功
        /// </summary>
        [Fact]
        public void GetById_Existing_ShouldReturnDetail()
        {
            _controller.Create(CreateRequest());
            int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_collect_address");

            var result = _controller.GetById(id);
            var response = ControllerFactory.Extract<CollectAddressDetailResponse>(result);
            ControllerFactory.AssertSuccess(response);
            Assert.Equal("地址1", response.Data.Name);
        }

        /// <summary>
        /// 测试：不存在的地址抛出异常
        /// </summary>
        [Fact]
        public void GetById_NotExisting_ShouldThrow()
        {
            Assert.Throws<BusinessException>(() => _controller.GetById(999));
        }

        #endregion

        #region Create - 新增地址

        /// <summary>
        /// 测试：新增地址成功
        /// </summary>
        [Fact]
        public void Create_ValidRequest_ShouldReturnId()
        {
            var result = _controller.Create(CreateRequest());
            var response = ControllerFactory.Extract<object>(result);
            ControllerFactory.AssertSuccess(response);
            Assert.NotNull(response.Data);
        }

        /// <summary>
        /// 测试：品牌不存在时抛出异常
        /// </summary>
        [Fact]
        public void Create_InvalidBrand_ShouldThrow()
        {
            var request = new CreateCollectAddressRequest
            {
                Name = "测试",
                Url = "http://test",
                BrandId = 999,
                CollectInterval = 5
            };
            Assert.Throws<BusinessException>(() => _controller.Create(request));
        }

        #endregion

        #region Update - 编辑地址

        /// <summary>
        /// 测试：编辑地址成功
        /// </summary>
        [Fact]
        public void Update_ValidRequest_ShouldSuccess()
        {
            _controller.Create(CreateRequest());
            int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_collect_address");

            var result = _controller.Update(id, new UpdateCollectAddressRequest
            {
                Name = "已改名",
                Url = "http://192.168.1.2",
                BrandId = 1,
                CollectInterval = 10
            });

            ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
            var detail = ControllerFactory.Extract<CollectAddressDetailResponse>(_controller.GetById(id));
            Assert.Equal("已改名", detail.Data.Name);
        }

        #endregion

        #region Delete - 删除地址

        /// <summary>
        /// 测试：删除地址成功
        /// </summary>
        [Fact]
        public void Delete_Existing_ShouldSuccess()
        {
            _controller.Create(CreateRequest());
            int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_collect_address");

            var result = _controller.Delete(id);
            ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
        }

        /// <summary>
        /// 测试：删除不存在的地址不抛异常（Service层影响0行但不抛异常）
        /// </summary>
        [Fact]
        public void Delete_NotExisting_ShouldNotThrow()
        {
            var result = _controller.Delete(999);
            Assert.NotNull(result);
        }

        #endregion

        #region ToggleEnabled - 启停

        /// <summary>
        /// 测试：切换地址启用状态
        /// </summary>
        [Fact]
        public void ToggleEnabled_ShouldSuccess()
        {
            _controller.Create(CreateRequest());
            int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_collect_address");

            var result = _controller.ToggleEnabled(id);
            ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
        }

        #endregion
    }
}
