using HoneyBox.Core.Interfaces;
using HoneyBox.Core.Services;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using HoneyBox.Model.Models.Lottery;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;

namespace HoneyBox.Tests.Integration;

/// <summary>
/// 抽奖服务集成测试
/// 测试抽奖结果查询、中奖记录查询功能
/// Requirements: 1.1-2.3, 4.1-4.3, 5.1-5.3
/// </summary>
public class LotteryServiceIntegrationTests
{
    private HoneyBoxDbContext CreateInMemoryDbContext()
    {
        var options = new DbContextOptionsBuilder<HoneyBoxDbContext>()
            .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
            .ConfigureWarnings(w => w.Ignore(InMemoryEventId.TransactionIgnoredWarning))
            .Options;

        return new HoneyBoxDbContext(options);
    }

    private LotteryService CreateLotteryService(HoneyBoxDbContext dbContext)
    {
        var mockLogger = new Mock<ILogger<LotteryService>>();
        var mockLotteryEngine = new Mock<ILotteryEngine>();
        return new LotteryService(dbContext, mockLotteryEngine.Object, mockLogger.Object);
    }

    #region 测试数据准备

    private async Task<User> CreateTestUserAsync(HoneyBoxDbContext dbContext, int id = 1, string nickname = "测试用户")
    {
        var user = new User
        {
            Id = id,
            OpenId = $"test_openid_{id}",
            Uid = $"test_uid_{id}",
            Nickname = nickname,
            HeadImg = "avatar.jpg",
            Mobile = "13800138000",
            Money = 100,
            Integral = 1000,
            Money2 = 500,
            IsTest = 0,
            Status = 1,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };
        await dbContext.Users.AddAsync(user);
        await dbContext.SaveChangesAsync();
        return user;
    }

    private async Task<Good> CreateTestGoodsAsync(HoneyBoxDbContext dbContext, int id = 1, byte type = 2, int status = 1)
    {
        var goods = new Good
        {
            Id = id,
            Title = "测试无限赏商品",
            Type = type, // 2 = 无限赏
            Status = (byte)status,
            ShowIs = 0,
            Price = 10,
            Stock = 100,
            SaleStock = 0,
            LockIs = 0,
            IsShouZhe = 0,
            QuanjuXiangou = 0,
            DailyXiangou = 0,
            ChoujiangXianzhi = 0,
            ImgUrl = "img.jpg",
            ImgUrlDetail = "detail.jpg"
        };
        await dbContext.Goods.AddAsync(goods);
        await dbContext.SaveChangesAsync();
        return goods;
    }

    private async Task CreateTestPrizeLevelsAsync(HoneyBoxDbContext dbContext)
    {
        var prizeLevels = new List<PrizeLevel>
        {
            new() { Id = 10, Title = "A赏", Color = "#FF0000", Sort = 1 },
            new() { Id = 11, Title = "B赏", Color = "#00FF00", Sort = 2 },
            new() { Id = 12, Title = "C赏", Color = "#0000FF", Sort = 3 }
        };
        await dbContext.PrizeLevels.AddRangeAsync(prizeLevels);
        await dbContext.SaveChangesAsync();
    }

    private async Task CreateTestGoodsItemsAsync(HoneyBoxDbContext dbContext, int goodsId)
    {
        var goodsItems = new List<GoodsItem>
        {
            new() { Id = 1, GoodsId = goodsId, Num = 0, Title = "A赏奖品", Stock = 5, SurplusStock = 5, Price = 100, ScMoney = 50, ShangId = 10, GoodsListId = 0, ImgUrl = "a.jpg", Sort = 1 },
            new() { Id = 2, GoodsId = goodsId, Num = 0, Title = "B赏奖品", Stock = 10, SurplusStock = 10, Price = 50, ScMoney = 25, ShangId = 11, GoodsListId = 0, ImgUrl = "b.jpg", Sort = 2 },
            new() { Id = 3, GoodsId = goodsId, Num = 0, Title = "C赏奖品", Stock = 20, SurplusStock = 20, Price = 30, ScMoney = 15, ShangId = 12, GoodsListId = 0, ImgUrl = "c.jpg", Sort = 3 }
        };
        await dbContext.GoodsItems.AddRangeAsync(goodsItems);
        await dbContext.SaveChangesAsync();
    }

    private async Task CreateTestOrderItemsAsync(HoneyBoxDbContext dbContext, int goodsId, int userId, int count = 5)
    {
        var now = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        var orderItems = new List<OrderItem>();
        
        for (int i = 1; i <= count; i++)
        {
            orderItems.Add(new OrderItem
            {
                Id = i,
                OrderId = 1,
                UserId = userId,
                GoodsId = goodsId,
                GoodslistId = i % 3 + 1,
                GoodslistTitle = $"奖品{i}",
                GoodslistImgurl = $"prize{i}.jpg",
                GoodslistPrice = 50 + i * 10,
                GoodslistMoney = 25 + i * 5,
                ShangId = 10 + (i % 3),
                Num = 0,
                OrderType = LotteryOrderType.WuXianShang, // 无限赏
                Source = PrizeSource.Lottery, // 抽奖获得
                Status = 0,
                LuckNo = i,
                Addtime = now - i * 60 // 每条记录间隔1分钟
            });
        }
        
        await dbContext.OrderItems.AddRangeAsync(orderItems);
        await dbContext.SaveChangesAsync();
    }

    private async Task<Order> CreateTestOrderAsync(HoneyBoxDbContext dbContext, int userId, int goodsId, string orderNum, int orderType = 1)
    {
        var order = new Order
        {
            Id = 1,
            UserId = userId,
            OrderNum = orderNum,
            GoodsId = goodsId,
            GoodsTitle = "测试商品",
            GoodsImgurl = "test.jpg",
            GoodsPrice = 10,
            OrderTotal = 50,
            OrderZheTotal = 50,
            Price = 50,
            PrizeNum = 5,
            Status = 1, // 已支付
            OrderType = (byte)orderType,
            Addtime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
            PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };
        await dbContext.Orders.AddAsync(order);
        await dbContext.SaveChangesAsync();
        return order;
    }

    private async Task CreateTestOrderItemsWithOrderAsync(HoneyBoxDbContext dbContext, int orderId, int goodsId, int userId, int orderType, int count = 5)
    {
        var now = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        var orderItems = new List<OrderItem>();
        
        for (int i = 1; i <= count; i++)
        {
            orderItems.Add(new OrderItem
            {
                Id = i,
                OrderId = orderId,
                UserId = userId,
                GoodsId = goodsId,
                GoodslistId = i % 3 + 1,
                GoodslistTitle = $"奖品{i}",
                GoodslistImgurl = $"prize{i}.jpg",
                GoodslistPrice = 50 + i * 10,
                GoodslistMoney = 25 + i * 5,
                ShangId = 10 + (i % 3),
                Num = 0,
                OrderType = (byte)orderType,
                Source = PrizeSource.Lottery,
                Status = 0,
                LuckNo = i,
                PrizeCode = $"P{DateTime.Now:yyyyMMddHHmmss}{1000 + i}",
                Addtime = now - i * 60
            });
        }
        
        await dbContext.OrderItems.AddRangeAsync(orderItems);
        await dbContext.SaveChangesAsync();
    }

    #endregion

    #region 一番赏抽奖结果查询测试 (Requirements 1.1-1.4)

    /// <summary>
    /// 测试一番赏抽奖结果查询 - 有效订单号返回奖品列表
    /// Requirements: 1.1
    /// </summary>
    [Fact]
    public async Task GetPrizeOrderLogAsync_ValidOrderNum_ReturnsPrizeList()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1); // 一番赏
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "TEST202601010001", orderType: 1);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.YiFanShang, 5);

        // Act
        var result = await service.GetPrizeOrderLogAsync(1, "TEST202601010001");

        // Assert
        Assert.NotNull(result);
        Assert.Equal(5, result.PrizeNum);
        Assert.Equal(5, result.Data.Count);
    }

    /// <summary>
    /// 测试一番赏抽奖结果查询 - 无效订单号返回空列表
    /// Requirements: 1.2
    /// </summary>
    [Fact]
    public async Task GetPrizeOrderLogAsync_InvalidOrderNum_ReturnsEmptyList()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);

        // Act
        var result = await service.GetPrizeOrderLogAsync(1, "INVALID_ORDER_NUM");

        // Assert
        Assert.NotNull(result);
        Assert.Equal(0, result.PrizeNum);
        Assert.Empty(result.Data);
    }

    /// <summary>
    /// 测试一番赏抽奖结果查询 - 返回奖品详情包含所有必要字段
    /// Requirements: 1.3
    /// </summary>
    [Fact]
    public async Task GetPrizeOrderLogAsync_ReturnsPrizeDetails_ContainsAllRequiredFields()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "TEST202601010002", orderType: 1);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.YiFanShang, 1);

        // Act
        var result = await service.GetPrizeOrderLogAsync(1, "TEST202601010002");

        // Assert
        Assert.NotNull(result);
        Assert.Single(result.Data);
        
        var prize = result.Data.First();
        Assert.NotEmpty(prize.GoodsListTitle); // title
        Assert.NotEmpty(prize.GoodsListImgUrl); // imgurl
        Assert.NotEmpty(prize.GoodsListPrice); // price
        Assert.NotEmpty(prize.GoodsListMoney); // recovery value (money)
        Assert.True(prize.LuckNo > 0); // luck_no
        Assert.True(prize.ShangId > 0); // shang_id
    }

    /// <summary>
    /// 测试一番赏抽奖结果查询 - 只返回当前用户的订单
    /// Requirements: 1.1
    /// </summary>
    [Fact]
    public async Task GetPrizeOrderLogAsync_OnlyReturnsCurrentUserOrder()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext, 1, "用户1");
        await CreateTestUserAsync(dbContext, 2, "用户2");
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        
        // 创建用户2的订单
        var order = await CreateTestOrderAsync(dbContext, 2, 1, "TEST202601010003", orderType: 1);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 2, LotteryOrderType.YiFanShang, 3);

        // Act - 用户1查询用户2的订单
        var result = await service.GetPrizeOrderLogAsync(1, "TEST202601010003");

        // Assert - 应该返回空，因为订单不属于用户1
        Assert.NotNull(result);
        Assert.Equal(0, result.PrizeNum);
        Assert.Empty(result.Data);
    }

    #endregion

    #region 无限赏抽奖结果查询测试 (Requirements 2.1-2.3)

    /// <summary>
    /// 测试无限赏抽奖结果查询 - 有效订单号返回奖品列表
    /// Requirements: 2.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeOrderLogAsync_ValidOrderNum_ReturnsPrizeList()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 2); // 无限赏
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "INF202601010001", orderType: 2);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.WuXianShang, 5);

        // Act
        var result = await service.GetInfinitePrizeOrderLogAsync(1, "INF202601010001");

        // Assert
        Assert.NotNull(result);
        Assert.Equal(5, result.PrizeNum);
        Assert.Equal(5, result.Data.Count);
    }

    /// <summary>
    /// 测试无限赏抽奖结果查询 - 只查询无限赏类型订单
    /// Requirements: 2.2
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeOrderLogAsync_OnlyReturnsInfiniteOrderType()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 2);
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "INF202601010002", orderType: 2);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.WuXianShang, 3);

        // Act
        var result = await service.GetInfinitePrizeOrderLogAsync(1, "INF202601010002");

        // Assert
        Assert.NotNull(result);
        Assert.Equal(3, result.Data.Count);
    }

    /// <summary>
    /// 测试无限赏抽奖结果查询 - 返回格式与一番赏一致
    /// Requirements: 2.3
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeOrderLogAsync_ResponseFormatConsistentWithYiFanShang()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 2);
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "INF202601010003", orderType: 2);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.WuXianShang, 1);

        // Act
        var result = await service.GetInfinitePrizeOrderLogAsync(1, "INF202601010003");

        // Assert
        Assert.NotNull(result);
        Assert.Single(result.Data);
        
        var prize = result.Data.First();
        // 验证与一番赏相同的字段
        Assert.NotEmpty(prize.GoodsListTitle);
        Assert.NotEmpty(prize.GoodsListImgUrl);
        Assert.NotEmpty(prize.GoodsListPrice);
        Assert.NotEmpty(prize.GoodsListMoney);
        Assert.True(prize.LuckNo > 0);
        Assert.True(prize.ShangId > 0);
    }

    /// <summary>
    /// 测试无限赏抽奖结果查询 - 包含用户信息
    /// Requirements: 2.3
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeOrderLogAsync_ContainsUserInfo()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext, nickname: "测试昵称");
        await CreateTestGoodsAsync(dbContext, type: 2);
        await CreateTestPrizeLevelsAsync(dbContext);
        var order = await CreateTestOrderAsync(dbContext, 1, 1, "INF202601010004", orderType: 2);
        await CreateTestOrderItemsWithOrderAsync(dbContext, order.Id, 1, 1, LotteryOrderType.WuXianShang, 1);

        // Act
        var result = await service.GetInfinitePrizeOrderLogAsync(1, "INF202601010004");

        // Assert
        Assert.NotNull(result);
        Assert.NotNull(result.UserInfo);
        Assert.NotEmpty(result.UserInfo.Nickname);
    }

    /// <summary>
    /// 测试无限赏抽奖结果查询 - 无效订单号返回空列表
    /// Requirements: 2.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeOrderLogAsync_InvalidOrderNum_ReturnsEmptyList()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);

        // Act
        var result = await service.GetInfinitePrizeOrderLogAsync(1, "INVALID_ORDER_NUM");

        // Assert
        Assert.NotNull(result);
        Assert.Equal(0, result.PrizeNum);
        Assert.Empty(result.Data);
    }

    #endregion

    #region 无限赏中奖记录查询测试 (Requirements 4.1-4.3)

    /// <summary>
    /// 测试无限赏中奖记录查询 - 基本查询
    /// Requirements: 4.1
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_BasicQuery_ReturnsRecords()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 5);

        // Act
        var result = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(5, result.Total);
        Assert.Equal(5, result.Data.Count);
        Assert.NotNull(result.Category);
        Assert.True(result.Category.Count > 0);
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 分页功能
    /// Requirements: 4.1
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_Pagination_ReturnsCorrectPage()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 15);

        // Act - 第一页
        var page1 = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);
        
        // Act - 第二页
        var page2 = await service.GetInfiniteShangLogAsync(1, 0, 0, 2, 10);

        // Assert
        Assert.Equal(15, page1.Total);
        Assert.Equal(2, page1.LastPage);
        Assert.Equal(10, page1.Data.Count);
        Assert.Equal(5, page2.Data.Count);
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 按赏品等级过滤
    /// Requirements: 4.2
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_FilterByShangId_ReturnsFilteredRecords()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 9); // 创建9条记录，每个等级3条

        // Act - 过滤A赏 (shangId = 10)
        var result = await service.GetInfiniteShangLogAsync(1, 10, 0, 1, 100);

        // Assert
        Assert.NotNull(result);
        Assert.True(result.Data.All(d => d.ShangId == 10));
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 商品不存在
    /// Requirements: 4.1
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_GoodsNotFound_ReturnsEmptyResult()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        // Act
        var result = await service.GetInfiniteShangLogAsync(999, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(0, result.Total);
        Assert.Empty(result.Data);
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 商品已下架
    /// Requirements: 4.1
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_GoodsOffline_ReturnsEmptyResult()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestGoodsAsync(dbContext, status: 0); // 下架状态

        // Act
        var result = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(0, result.Total);
        Assert.Empty(result.Data);
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 用户昵称脱敏
    /// Requirements: 4.3
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_UserNicknameMasked_ReturnsMaskedNickname()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext, nickname: "测试用户名");
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 1);

        // Act
        var result = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Single(result.Data);
        var record = result.Data.First();
        Assert.NotNull(record.UserInfo);
        // 验证昵称已脱敏（包含***）
        Assert.Contains("***", record.UserInfo.Nickname);
    }

    /// <summary>
    /// 测试无限赏中奖记录查询 - 分类列表包含全部选项
    /// Requirements: 4.1
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_CategoryList_ContainsAllOption()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);

        // Act
        var result = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result.Category);
        Assert.True(result.Category.Count > 0);
        Assert.Equal(0, result.Category.First().ShangId);
        Assert.Equal("全部", result.Category.First().ShangTitle);
    }

    #endregion

    #region 每日抽奖记录查询测试 (Requirements 5.1-5.3)

    /// <summary>
    /// 测试每日抽奖记录查询 - 基本查询
    /// Requirements: 5.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_BasicQuery_ReturnsRecords()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 5);

        // Act
        var result = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(5, result.Total);
        Assert.Equal(5, result.Data.Count);
    }

    /// <summary>
    /// 测试每日抽奖记录查询 - 分页功能
    /// Requirements: 5.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_Pagination_ReturnsCorrectPage()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 15);

        // Act - 第一页
        var page1 = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 10);
        
        // Act - 第二页
        var page2 = await service.GetInfinitePrizeRecordsAsync(1, 1, 2, 10);

        // Assert
        Assert.Equal(15, page1.Total);
        Assert.Equal(2, page1.LastPage);
        Assert.Equal(10, page1.Data.Count);
        Assert.Equal(5, page2.Data.Count);
    }

    /// <summary>
    /// 测试每日抽奖记录查询 - 只返回当前用户的记录
    /// Requirements: 5.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_OnlyCurrentUserRecords_ReturnsFilteredRecords()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext, 1, "用户1");
        await CreateTestUserAsync(dbContext, 2, "用户2");
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        
        // 为用户1创建5条记录
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 5);
        
        // 为用户2创建3条记录
        var now = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        var user2Items = new List<OrderItem>();
        for (int i = 6; i <= 8; i++)
        {
            user2Items.Add(new OrderItem
            {
                Id = i,
                OrderId = 2,
                UserId = 2,
                GoodsId = 1,
                GoodslistId = 1,
                GoodslistTitle = $"奖品{i}",
                GoodslistImgurl = $"prize{i}.jpg",
                GoodslistPrice = 50,
                GoodslistMoney = 25,
                ShangId = 10,
                Num = 0,
                OrderType = LotteryOrderType.WuXianShang,
                Source = PrizeSource.Lottery,
                Status = 0,
                LuckNo = i,
                Addtime = now - i * 60
            });
        }
        await dbContext.OrderItems.AddRangeAsync(user2Items);
        await dbContext.SaveChangesAsync();

        // Act - 查询用户1的记录
        var result = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 100);

        // Assert
        Assert.Equal(5, result.Total);
        Assert.All(result.Data, d => Assert.Equal(1, d.UserId));
    }

    /// <summary>
    /// 测试每日抽奖记录查询 - 无记录时返回空列表
    /// Requirements: 5.1
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_NoRecords_ReturnsEmptyList()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);

        // Act
        var result = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(0, result.Total);
        Assert.Empty(result.Data);
    }

    /// <summary>
    /// 测试每日抽奖记录查询 - 记录按时间倒序排列
    /// Requirements: 5.3
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_OrderByTimeDescending_ReturnsOrderedRecords()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 5);

        // Act
        var result = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Equal(5, result.Data.Count);
        
        // 验证记录按ID倒序（ID越大时间越新）
        var ids = result.Data.Select(d => d.UserId).ToList();
        // 由于我们按id倒序，第一条应该是最新的
    }

    #endregion

    #region 响应格式测试 (Requirements 10.1-10.4)

    /// <summary>
    /// 测试响应格式 - 无限赏中奖记录包含所有必要字段
    /// Requirements: 10.2
    /// </summary>
    [Fact]
    public async Task GetInfiniteShangLogAsync_ResponseFormat_ContainsAllRequiredFields()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 1);

        // Act
        var result = await service.GetInfiniteShangLogAsync(1, 0, 0, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Single(result.Data);
        
        var record = result.Data.First();
        Assert.True(record.Id > 0);
        Assert.True(record.UserId > 0);
        Assert.NotEmpty(record.GoodslistTitle);
        Assert.NotEmpty(record.GoodslistImgurl);
        Assert.NotEmpty(record.GoodslistPrice);
        Assert.NotEmpty(record.GoodslistMoney);
        Assert.True(record.ShangId > 0);
        Assert.NotEmpty(record.Addtime);
    }

    /// <summary>
    /// 测试响应格式 - 每日抽奖记录包含所有必要字段
    /// Requirements: 10.2
    /// </summary>
    [Fact]
    public async Task GetInfinitePrizeRecordsAsync_ResponseFormat_ContainsAllRequiredFields()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsAsync(dbContext, 1);
        await CreateTestOrderItemsAsync(dbContext, 1, 1, 1);

        // Act
        var result = await service.GetInfinitePrizeRecordsAsync(1, 1, 1, 10);

        // Assert
        Assert.NotNull(result);
        Assert.Single(result.Data);
        
        var record = result.Data.First();
        Assert.True(record.UserId > 0);
        Assert.NotEmpty(record.GoodslistTitle);
        Assert.NotEmpty(record.GoodslistImgurl);
        Assert.NotEmpty(record.Addtime);
    }

    #endregion

    #region 道具卡抽奖测试 (Requirements 6.1-6.4)

    private async Task<UserItemCard> CreateTestItemCardAsync(HoneyBoxDbContext dbContext, int userId, int status = 1)
    {
        var itemCard = new UserItemCard
        {
            Id = 1,
            UserId = userId,
            Type = 1,
            ItemCardId = 1,
            Title = "重抽卡",
            Status = (byte)status, // 1=未使用，2=已使用
            Addtime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
            Updatetime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()
        };
        await dbContext.UserItemCards.AddAsync(itemCard);
        await dbContext.SaveChangesAsync();
        return itemCard;
    }

    private LotteryService CreateLotteryServiceWithMockedEngine(HoneyBoxDbContext dbContext, Mock<ILotteryEngine> mockEngine)
    {
        var mockLogger = new Mock<ILogger<LotteryService>>();
        return new LotteryService(dbContext, mockEngine.Object, mockLogger.Object);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 商品不存在时返回错误
    /// Requirements: 6.1
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_GoodsNotFound_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestItemCardAsync(dbContext, 1);

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 999, new List<int> { 1 }));
        
        Assert.Equal("盒子不存在", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 商品已下架时返回错误
    /// Requirements: 6.1
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_GoodsOffline_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, status: 0); // 下架状态
        await CreateTestItemCardAsync(dbContext, 1);

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int> { 1 }));
        
        Assert.Equal("盒子已下架", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 道具卡数量不足时返回错误
    /// Requirements: 6.4
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_NoItemCards_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        // 不创建道具卡

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int> { 1 }));
        
        Assert.Equal("重抽卡数量不足", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 道具卡已使用时返回错误
    /// Requirements: 6.4
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_ItemCardAlreadyUsed_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestItemCardAsync(dbContext, 1, status: 2); // 已使用状态

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int> { 1 }));
        
        Assert.Equal("重抽卡数量不足", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 参数为空时返回错误
    /// Requirements: 6.4
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_EmptyOrderListIds_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestItemCardAsync(dbContext, 1);

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int>()));
        
        Assert.Equal("参数错误", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 订单项不存在时返回错误
    /// Requirements: 6.4
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_OrderItemNotFound_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext);
        await CreateTestItemCardAsync(dbContext, 1);

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int> { 999 }));
        
        Assert.Equal("数据错误", exception.Message);
    }

    /// <summary>
    /// 测试道具卡抽奖 - 消费门槛验证
    /// Requirements: 6.1
    /// </summary>
    [Fact]
    public async Task DrawWithItemCardAsync_SpendingThresholdNotMet_ThrowsException()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var service = CreateLotteryService(dbContext);

        await CreateTestUserAsync(dbContext);
        // 创建有消费门槛的商品
        var goods = new Good
        {
            Id = 1,
            Title = "测试商品",
            Type = 2,
            Status = 1,
            Price = 10,
            Stock = 100,
            ChoujiangXianzhi = 1000, // 消费门槛1000元
            ImgUrl = "img.jpg",
            ImgUrlDetail = "detail.jpg",
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };
        await dbContext.Goods.AddAsync(goods);
        await dbContext.SaveChangesAsync();
        
        await CreateTestItemCardAsync(dbContext, 1);

        // Act & Assert
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(
            () => service.DrawWithItemCardAsync(1, 1, new List<int> { 1 }));
        
        Assert.Contains("消费满", exception.Message);
    }

    // Note: The test for valid item card draw (DrawWithItemCardAsync_ValidItemCard_ExecutesDrawAndMarksCardAsUsed)
    // is skipped because InMemory database does not support ExecuteUpdateAsync.
    // This functionality should be tested with a real database in end-to-end tests.

    #endregion

    #region 抽奖引擎集成测试 (Requirements 7.1-9.4)

    private LotteryEngine CreateLotteryEngine(HoneyBoxDbContext dbContext, IInventoryManager inventoryManager)
    {
        var mockLogger = new Mock<ILogger<LotteryEngine>>();
        var mockRewardService = new Mock<IRewardService>();
        return new LotteryEngine(dbContext, inventoryManager, mockRewardService.Object, mockLogger.Object);
    }

    private InventoryManager CreateInventoryManager(HoneyBoxDbContext dbContext)
    {
        var mockLogger = new Mock<ILogger<InventoryManager>>();
        return new InventoryManager(dbContext, mockLogger.Object);
    }

    private async Task CreateTestGoodsItemsWithStockAsync(HoneyBoxDbContext dbContext, int goodsId, int num = 0)
    {
        var goodsItems = new List<GoodsItem>
        {
            new() { Id = 101, GoodsId = goodsId, Num = num, Title = "A赏奖品", Stock = 5, SurplusStock = 5, Price = 100, ScMoney = 50, ShangId = 10, GoodsListId = 0, ImgUrl = "a.jpg", Sort = 1 },
            new() { Id = 102, GoodsId = goodsId, Num = num, Title = "B赏奖品", Stock = 10, SurplusStock = 10, Price = 50, ScMoney = 25, ShangId = 11, GoodsListId = 0, ImgUrl = "b.jpg", Sort = 2 },
            new() { Id = 103, GoodsId = goodsId, Num = num, Title = "C赏奖品", Stock = 20, SurplusStock = 20, Price = 30, ScMoney = 15, ShangId = 12, GoodsListId = 0, ImgUrl = "c.jpg", Sort = 3 }
        };
        await dbContext.GoodsItems.AddRangeAsync(goodsItems);
        await dbContext.SaveChangesAsync();
    }

    /// <summary>
    /// 测试抽奖引擎 - 完整抽奖流程成功
    /// Requirements: 7.1-7.7
    /// </summary>
    [Fact]
    public async Task LotteryEngine_DrawAsync_CompletesSuccessfully()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        // Act
        var result = await engine.DrawAsync(request);

        // Assert
        Assert.True(result.Success);
        Assert.True(result.GoodsItemId > 0);
        Assert.NotEmpty(result.Title);
        Assert.NotEmpty(result.PrizeCode);
        Assert.True(result.LuckNo > 0);
        Assert.True(result.OrderItemId > 0);
    }

    /// <summary>
    /// 测试抽奖引擎 - 库存扣减正确
    /// Requirements: 8.1-8.4
    /// </summary>
    [Fact]
    public async Task LotteryEngine_DrawAsync_DeductsStockCorrectly()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        // 获取初始总库存
        var initialTotalStock = await dbContext.GoodsItems
            .Where(gi => gi.GoodsId == 1 && gi.Num == 0)
            .SumAsync(gi => gi.SurplusStock);

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        // Act
        var result = await engine.DrawAsync(request);

        // Assert
        Assert.True(result.Success);
        
        // 验证库存已扣减
        var finalTotalStock = await dbContext.GoodsItems
            .Where(gi => gi.GoodsId == 1 && gi.Num == 0)
            .SumAsync(gi => gi.SurplusStock);
        
        Assert.Equal(initialTotalStock - 1, finalTotalStock);
    }

    /// <summary>
    /// 测试抽奖引擎 - 抽奖记录创建正确
    /// Requirements: 9.1-9.4
    /// </summary>
    [Fact]
    public async Task LotteryEngine_DrawAsync_CreatesRecordCorrectly()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        // Act
        var result = await engine.DrawAsync(request);

        // Assert
        Assert.True(result.Success);
        
        // 验证记录已创建
        var orderItem = await dbContext.OrderItems.FindAsync(result.OrderItemId);
        Assert.NotNull(orderItem);
        Assert.Equal(1, orderItem.UserId);
        Assert.Equal(1, orderItem.GoodsId);
        Assert.Equal(result.GoodsItemId, orderItem.GoodslistId);
        Assert.Equal(result.ShangId, orderItem.ShangId);
        Assert.Equal(result.PrizeCode, orderItem.PrizeCode);
        Assert.Equal(result.LuckNo, orderItem.LuckNo);
        Assert.Equal((byte)PrizeSource.Lottery, orderItem.Source);
    }

    /// <summary>
    /// 测试抽奖引擎 - 无可用奖品时返回失败
    /// Requirements: 7.3
    /// </summary>
    [Fact]
    public async Task LotteryEngine_DrawAsync_NoPrizes_ReturnsFailed()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        // 不创建奖品

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        // Act
        var result = await engine.DrawAsync(request);

        // Assert
        Assert.False(result.Success);
        Assert.Equal("暂无可抽奖品", result.ErrorMessage);
    }

    /// <summary>
    /// 测试抽奖引擎 - 多次抽奖成功
    /// Requirements: 7.1-7.7
    /// </summary>
    [Fact]
    public async Task LotteryEngine_DrawMultipleAsync_CompletesSuccessfully()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        // Act
        var results = await engine.DrawMultipleAsync(request, 3);

        // Assert
        Assert.Equal(3, results.Count);
        Assert.All(results, r => Assert.True(r.Success));
        
        // 验证每次抽奖都创建了记录
        var orderItemCount = await dbContext.OrderItems.CountAsync();
        Assert.Equal(3, orderItemCount);
    }

    /// <summary>
    /// 测试抽奖引擎 - 概率计算正确
    /// Requirements: 7.1
    /// </summary>
    [Fact]
    public async Task LotteryEngine_CalculateProbabilitiesAsync_ReturnsCorrectProbabilities()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        // Act
        var probabilities = await engine.CalculateProbabilitiesAsync(1, 0);

        // Assert
        Assert.Equal(3, probabilities.Count);
        
        // 验证概率总和为100%
        var totalProbability = probabilities.Sum(p => p.Probability);
        Assert.Equal(100m, totalProbability, 2);
        
        // 验证概率与库存成正比
        // A赏: 5/(5+10+20) = 14.29%
        // B赏: 10/(5+10+20) = 28.57%
        // C赏: 20/(5+10+20) = 57.14%
        var aPrize = probabilities.First(p => p.ShangId == 10);
        var bPrize = probabilities.First(p => p.ShangId == 11);
        var cPrize = probabilities.First(p => p.ShangId == 12);
        
        Assert.True(cPrize.Probability > bPrize.Probability);
        Assert.True(bPrize.Probability > aPrize.Probability);
    }

    /// <summary>
    /// 测试抽奖引擎 - 库存为0的奖品被排除
    /// Requirements: 7.3
    /// </summary>
    [Fact]
    public async Task LotteryEngine_CalculateProbabilitiesAsync_ExcludesZeroStockPrizes()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestGoodsAsync(dbContext, type: 1);
        
        // 创建包含库存为0的奖品
        var goodsItems = new List<GoodsItem>
        {
            new() { Id = 201, GoodsId = 1, Num = 0, Title = "A赏奖品", Stock = 5, SurplusStock = 0, Price = 100, ScMoney = 50, ShangId = 10, GoodsListId = 0, ImgUrl = "a.jpg", Sort = 1 },
            new() { Id = 202, GoodsId = 1, Num = 0, Title = "B赏奖品", Stock = 10, SurplusStock = 10, Price = 50, ScMoney = 25, ShangId = 11, GoodsListId = 0, ImgUrl = "b.jpg", Sort = 2 }
        };
        await dbContext.GoodsItems.AddRangeAsync(goodsItems);
        await dbContext.SaveChangesAsync();

        // Act
        var probabilities = await engine.CalculateProbabilitiesAsync(1, 0);

        // Assert
        Assert.Single(probabilities);
        Assert.Equal(11, probabilities.First().ShangId);
        Assert.Equal(100m, probabilities.First().Probability);
    }

    /// <summary>
    /// 测试抽奖引擎 - 验证抽奖结果
    /// Requirements: 9.1-9.4
    /// </summary>
    [Fact]
    public async Task LotteryEngine_ValidateDrawResultAsync_ValidResult_ReturnsTrue()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        await CreateTestUserAsync(dbContext);
        await CreateTestGoodsAsync(dbContext, type: 1);
        await CreateTestPrizeLevelsAsync(dbContext);
        await CreateTestGoodsItemsWithStockAsync(dbContext, 1);

        var request = new LotteryDrawRequest
        {
            UserId = 1,
            GoodsId = 1,
            Num = 0,
            OrderId = 1,
            OrderType = LotteryOrderType.YiFanShang,
            Source = PrizeSource.Lottery
        };

        var drawResult = await engine.DrawAsync(request);

        // Act
        var isValid = await engine.ValidateDrawResultAsync(drawResult);

        // Assert
        Assert.True(isValid);
    }

    /// <summary>
    /// 测试抽奖引擎 - 验证失败的抽奖结果
    /// Requirements: 9.1-9.4
    /// </summary>
    [Fact]
    public async Task LotteryEngine_ValidateDrawResultAsync_FailedResult_ReturnsFalse()
    {
        // Arrange
        var dbContext = CreateInMemoryDbContext();
        var inventoryManager = CreateInventoryManager(dbContext);
        var engine = CreateLotteryEngine(dbContext, inventoryManager);

        var failedResult = new LotteryDrawResult { Success = false };

        // Act
        var isValid = await engine.ValidateDrawResultAsync(failedResult);

        // Assert
        Assert.False(isValid);
    }

    #endregion
}

