using FsCheck;
using FsCheck.Xunit;
using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.User;
using HoneyBox.Admin.Business.Services;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;

namespace HoneyBox.Tests.Services;

/// <summary>
/// 用户管理前端模块属性测试
/// Feature: user-management-frontend
/// </summary>
public class UserManagementFrontendPropertyTests
{
    private readonly Mock<ILogger<UserBusinessService>> _mockLogger = new();

    #region Property 1: 搜索参数正确传递

    /// <summary>
    /// **Feature: user-management-frontend, Property 1: 搜索参数正确传递**
    /// For any user list search request, when the admin inputs search conditions,
    /// the API call query parameters should exactly match the user input search conditions.
    /// **Validates: Requirements 1.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool SearchParameters_ShouldFilterCorrectly_ByNickname(PositiveInt seed)
    {
        var nicknames = new[] { "Alice", "Bob", "Charlie", "David", "Eve" };
        var searchNickname = nicknames[seed.Get % nicknames.Length];

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create users with different nicknames
        foreach (var name in nicknames)
        {
            dbContext.Users.Add(CreateTestUser(name));
            dbContext.Users.Add(CreateTestUser($"{name}Smith"));
        }
        dbContext.SaveChanges();

        var request = new UserListRequest { Nickname = searchNickname };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        // All returned users should contain the search nickname
        return result.List.All(u => u.Nickname != null && u.Nickname.Contains(searchNickname));
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 1: 搜索参数正确传递**
    /// For any user list search request with mobile filter,
    /// all returned users should have matching mobile numbers.
    /// **Validates: Requirements 1.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool SearchParameters_ShouldFilterCorrectly_ByMobile(PositiveInt seed)
    {
        var mobilePrefix = $"138{(seed.Get % 100):D2}";

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create users with different mobile numbers
        for (int i = 0; i < 10; i++)
        {
            var user = CreateTestUser($"User{i}");
            user.Mobile = i < 5 ? $"{mobilePrefix}{i:D6}" : $"139{i:D8}";
            dbContext.Users.Add(user);
        }
        dbContext.SaveChanges();

        var request = new UserListRequest { Mobile = mobilePrefix };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        // All returned users should have mobile containing the prefix
        return result.List.All(u => u.Mobile != null && u.Mobile.Contains(mobilePrefix));
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 1: 搜索参数正确传递**
    /// For any user list search request with parent ID filter,
    /// all returned users should have the specified parent ID.
    /// **Validates: Requirements 1.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool SearchParameters_ShouldFilterCorrectly_ByParentId(PositiveInt seed)
    {
        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create parent user
        var parent = CreateTestUser("Parent");
        dbContext.Users.Add(parent);
        dbContext.SaveChanges();

        // Create subordinate users
        var subordinateCount = (seed.Get % 5) + 1;
        for (int i = 0; i < subordinateCount; i++)
        {
            var child = CreateTestUser($"Child{i}");
            child.Pid = parent.Id;
            dbContext.Users.Add(child);
        }

        // Create other users without parent
        for (int i = 0; i < 3; i++)
        {
            dbContext.Users.Add(CreateTestUser($"Other{i}"));
        }
        dbContext.SaveChanges();

        var request = new UserListRequest { ParentId = parent.Id };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        // All returned users should have the specified parent ID
        return result.Total == subordinateCount &&
               result.List.All(u => u.ParentId == parent.Id);
    }

    #endregion

    #region Property 2: 分页参数正确传递

    /// <summary>
    /// **Feature: user-management-frontend, Property 2: 分页参数正确传递**
    /// For any pagination request, the returned list should have at most pageSize items,
    /// and the page and pageSize in response should match the request.
    /// **Validates: Requirements 1.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool PaginationParameters_ShouldReturnCorrectPageSize(PositiveInt seed)
    {
        var userCount = (seed.Get % 30) + 10; // 10 to 39 users
        var pageSize = (seed.Get % 10) + 1; // 1 to 10 per page
        var page = (seed.Get % 5) + 1; // page 1 to 5

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test users
        for (int i = 0; i < userCount; i++)
        {
            dbContext.Users.Add(CreateTestUser($"User{i}"));
        }
        dbContext.SaveChanges();

        var request = new UserListRequest { Page = page, PageSize = pageSize };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        // Verify pagination parameters are correctly passed
        return result.Total == userCount &&
               result.List.Count <= pageSize &&
               result.Page == page &&
               result.PageSize == pageSize;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 2: 分页参数正确传递**
    /// The total count should remain consistent regardless of which page is requested.
    /// **Validates: Requirements 1.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool PaginationParameters_TotalShouldBeConsistentAcrossPages(PositiveInt seed)
    {
        var userCount = (seed.Get % 20) + 15; // 15 to 34 users
        var pageSize = 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test users
        for (int i = 0; i < userCount; i++)
        {
            dbContext.Users.Add(CreateTestUser($"User{i}"));
        }
        dbContext.SaveChanges();

        // Get multiple pages
        var page1 = service.GetUserListAsync(new UserListRequest { Page = 1, PageSize = pageSize }).GetAwaiter().GetResult();
        var page2 = service.GetUserListAsync(new UserListRequest { Page = 2, PageSize = pageSize }).GetAwaiter().GetResult();
        var page3 = service.GetUserListAsync(new UserListRequest { Page = 3, PageSize = pageSize }).GetAwaiter().GetResult();

        // Total should be consistent across all pages
        return page1.Total == page2.Total && 
               page2.Total == page3.Total && 
               page1.Total == userCount;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 2: 分页参数正确传递**
    /// Different pages should return different users (no overlap).
    /// **Validates: Requirements 1.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool PaginationParameters_DifferentPagesShouldNotOverlap(PositiveInt seed)
    {
        var userCount = (seed.Get % 15) + 20; // 20 to 34 users
        var pageSize = 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test users
        for (int i = 0; i < userCount; i++)
        {
            dbContext.Users.Add(CreateTestUser($"User{i}"));
        }
        dbContext.SaveChanges();

        // Get first two pages
        var page1 = service.GetUserListAsync(new UserListRequest { Page = 1, PageSize = pageSize }).GetAwaiter().GetResult();
        var page2 = service.GetUserListAsync(new UserListRequest { Page = 2, PageSize = pageSize }).GetAwaiter().GetResult();

        // User IDs should not overlap between pages
        var page1Ids = page1.List.Select(u => u.Id).ToHashSet();
        var page2Ids = page2.List.Select(u => u.Id).ToHashSet();

        return !page1Ids.Overlaps(page2Ids);
    }

    #endregion


    #region Property 3: 资金变动参数验证

    /// <summary>
    /// **Feature: user-management-frontend, Property 3: 资金变动参数验证**
    /// When operation type is "subtract" and amount is greater than user's current balance,
    /// the system should throw an exception instead of executing the subtraction.
    /// **Validates: Requirements 2.3**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool MoneyChangeValidation_ShouldRejectInsufficientBalance(PositiveInt seed)
    {
        var initialBalance = (seed.Get % 100) + 10; // 10 to 109
        var subtractAmount = initialBalance + (seed.Get % 50) + 1; // Always more than balance

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user with limited balance
        var user = CreateTestUser("TestUser");
        user.Money = initialBalance;
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var request = new UserMoneyChangeRequest
        {
            Type = MoneyChangeType.Balance,
            Amount = subtractAmount,
            Operation = OperationType.Subtract,
            Remark = "Property test - insufficient balance"
        };

        try
        {
            service.ChangeUserMoneyAsync(user.Id, request, 1).GetAwaiter().GetResult();
            return false; // Should have thrown exception
        }
        catch (BusinessException ex)
        {
            // Verify user balance was not changed
            var updatedUser = dbContext.Users.Find(user.Id);
            return ex.Message.Contains("余额不足") && updatedUser!.Money == initialBalance;
        }
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 3: 资金变动参数验证**
    /// When operation type is "add", the balance should increase by exactly the specified amount.
    /// **Validates: Requirements 2.3**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool MoneyChangeValidation_AddShouldIncreaseBalanceExactly(PositiveInt seed)
    {
        var initialBalance = (seed.Get % 500) + 100; // 100 to 599
        var addAmount = (seed.Get % 100) + 1; // 1 to 100

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        user.Money = initialBalance;
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var request = new UserMoneyChangeRequest
        {
            Type = MoneyChangeType.Balance,
            Amount = addAmount,
            Operation = OperationType.Add,
            Remark = "Property test - add balance"
        };

        service.ChangeUserMoneyAsync(user.Id, request, 1).GetAwaiter().GetResult();

        // Refresh user from database
        var updatedUser = dbContext.Users.Find(user.Id);
        return updatedUser!.Money == initialBalance + addAmount;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 3: 资金变动参数验证**
    /// When operation type is "subtract" and amount is less than or equal to balance,
    /// the balance should decrease by exactly the specified amount.
    /// **Validates: Requirements 2.3**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool MoneyChangeValidation_SubtractShouldDecreaseBalanceExactly(PositiveInt seed)
    {
        var initialBalance = (seed.Get % 500) + 200; // 200 to 699
        var subtractAmount = (seed.Get % 100) + 1; // 1 to 100 (always less than balance)

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        user.Money = initialBalance;
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var request = new UserMoneyChangeRequest
        {
            Type = MoneyChangeType.Balance,
            Amount = subtractAmount,
            Operation = OperationType.Subtract,
            Remark = "Property test - subtract balance"
        };

        service.ChangeUserMoneyAsync(user.Id, request, 1).GetAwaiter().GetResult();

        // Refresh user from database
        var updatedUser = dbContext.Users.Find(user.Id);
        return updatedUser!.Money == initialBalance - subtractAmount;
    }

    #endregion

    #region Property 4: 用户状态切换一致性

    /// <summary>
    /// **Feature: user-management-frontend, Property 4: 用户状态切换一致性**
    /// Ban operation should set status to 0, unban operation should set status to 1,
    /// and the user list should display the correct status after the operation.
    /// **Validates: Requirements 3.1, 3.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool UserStatusToggle_BanShouldSetStatusToZero(PositiveInt seed)
    {
        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user with status 1 (active)
        var user = CreateTestUser("TestUser");
        user.Status = 1;
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        // Ban the user (set status to 0)
        var result = service.SetUserStatusAsync(user.Id, 0).GetAwaiter().GetResult();
        if (!result) return false;

        // Verify status was set to 0
        var updatedUser = dbContext.Users.Find(user.Id);
        return updatedUser!.Status == 0;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 4: 用户状态切换一致性**
    /// Unban operation should set status to 1.
    /// **Validates: Requirements 3.1, 3.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool UserStatusToggle_UnbanShouldSetStatusToOne(PositiveInt seed)
    {
        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user with status 0 (banned)
        var user = CreateTestUser("TestUser");
        user.Status = 0;
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        // Unban the user (set status to 1)
        var result = service.SetUserStatusAsync(user.Id, 1).GetAwaiter().GetResult();
        if (!result) return false;

        // Verify status was set to 1
        var updatedUser = dbContext.Users.Find(user.Id);
        return updatedUser!.Status == 1;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 4: 用户状态切换一致性**
    /// Status toggle should be idempotent - setting the same status multiple times
    /// should result in the same final state.
    /// **Validates: Requirements 3.1, 3.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool UserStatusToggle_ShouldBeIdempotent(PositiveInt seed)
    {
        var targetStatus = seed.Get % 2; // 0 or 1

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        user.Status = (byte)(1 - targetStatus); // Start with opposite status
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        // Set status multiple times
        service.SetUserStatusAsync(user.Id, targetStatus).GetAwaiter().GetResult();
        service.SetUserStatusAsync(user.Id, targetStatus).GetAwaiter().GetResult();
        service.SetUserStatusAsync(user.Id, targetStatus).GetAwaiter().GetResult();

        // Verify status is correct
        var updatedUser = dbContext.Users.Find(user.Id);
        return updatedUser!.Status == targetStatus;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 4: 用户状态切换一致性**
    /// User list should reflect the correct status after status change.
    /// **Validates: Requirements 3.1, 3.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool UserStatusToggle_ListShouldReflectCorrectStatus(PositiveInt seed)
    {
        var targetStatus = seed.Get % 2; // 0 or 1

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        user.Status = (byte)(1 - targetStatus);
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        // Change status
        service.SetUserStatusAsync(user.Id, targetStatus).GetAwaiter().GetResult();

        // Get user list and verify status
        var request = new UserListRequest { UserId = user.Id };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        return result.List.Count == 1 && result.List[0].Status == targetStatus;
    }

    #endregion


    #region Property 5: 盈亏计算正确性

    /// <summary>
    /// **Feature: user-management-frontend, Property 5: 盈亏计算正确性**
    /// Profit/loss amount should equal: User payment - Shipping amount - Backpack amount - Remaining DaDa coupons,
    /// and profit status should correctly display based on whether the amount is positive or negative.
    /// **Validates: Requirements 6.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ProfitLossCalculation_ShouldBeCorrect(PositiveInt seed)
    {
        // Generate test data
        var useMoney = (seed.Get % 1000) + 100m; // 100 to 1099
        var fhMoney = (seed.Get % 500) + 50m; // 50 to 549
        var bbMoney = (seed.Get % 300) + 20m; // 20 to 319
        var syMoney = (seed.Get % 100) + 10m; // 10 to 109

        // Calculate expected profit/loss
        var expectedYueMoney = useMoney - fhMoney - bbMoney - syMoney;
        var expectedStatus = expectedYueMoney >= 0 ? "盈利" : "亏损";

        // Create a ProfitLossItem and verify calculation
        var item = new ProfitLossItem
        {
            UserId = 1,
            Uid = "TEST001",
            Nickname = "TestUser",
            UseMoney = useMoney,
            FhMoney = fhMoney,
            BbMoney = bbMoney,
            SyMoney = syMoney,
            YueMoney = expectedYueMoney,
            ProfitStatus = expectedStatus
        };

        // Verify the calculation formula
        var calculatedYueMoney = item.UseMoney - item.FhMoney - item.BbMoney - item.SyMoney;
        var calculatedStatus = calculatedYueMoney >= 0 ? "盈利" : "亏损";

        return item.YueMoney == calculatedYueMoney && item.ProfitStatus == calculatedStatus;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 5: 盈亏计算正确性**
    /// When user payment equals total deductions, profit/loss should be zero and status should be "盈利".
    /// **Validates: Requirements 6.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ProfitLossCalculation_ZeroShouldBeProfit(PositiveInt seed)
    {
        var useMoney = (seed.Get % 1000) + 100m;
        var fhMoney = useMoney / 3;
        var bbMoney = useMoney / 3;
        var syMoney = useMoney - fhMoney - bbMoney; // Make total equal to useMoney

        var yueMoney = useMoney - fhMoney - bbMoney - syMoney;
        var status = yueMoney >= 0 ? "盈利" : "亏损";

        // Zero or positive should be "盈利"
        return yueMoney == 0 && status == "盈利";
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 5: 盈亏计算正确性**
    /// When deductions exceed payment, profit/loss should be negative and status should be "亏损".
    /// **Validates: Requirements 6.4**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ProfitLossCalculation_NegativeShouldBeLoss(PositiveInt seed)
    {
        var useMoney = (seed.Get % 100) + 50m; // 50 to 149
        var fhMoney = useMoney + (seed.Get % 50) + 10m; // Always more than useMoney
        var bbMoney = 0m;
        var syMoney = 0m;

        var yueMoney = useMoney - fhMoney - bbMoney - syMoney;
        var status = yueMoney >= 0 ? "盈利" : "亏损";

        // Negative should be "亏损"
        return yueMoney < 0 && status == "亏损";
    }

    #endregion

    #region Property 6: API响应格式一致性

    /// <summary>
    /// **Feature: user-management-frontend, Property 6: API响应格式一致性**
    /// For any backend API response, the response format should conform to the unified ApiResponse structure.
    /// **Validates: Requirements 10.1-10.10**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ApiResponseFormat_PagedResultShouldHaveConsistentStructure(PositiveInt seed)
    {
        var userCount = (seed.Get % 20) + 5;
        var page = (seed.Get % 3) + 1;
        var pageSize = (seed.Get % 10) + 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test users
        for (int i = 0; i < userCount; i++)
        {
            dbContext.Users.Add(CreateTestUser($"User{i}"));
        }
        dbContext.SaveChanges();

        var request = new UserListRequest { Page = page, PageSize = pageSize };
        var result = service.GetUserListAsync(request).GetAwaiter().GetResult();

        // Verify PagedResult structure
        return result != null &&
               result.List != null &&
               result.Total >= 0 &&
               result.Page == page &&
               result.PageSize == pageSize &&
               result.TotalPages == (int)Math.Ceiling((double)result.Total / result.PageSize);
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 6: API响应格式一致性**
    /// User box API should return consistent PagedResult structure.
    /// **Validates: Requirements 10.1**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ApiResponseFormat_UserBoxShouldHaveConsistentStructure(PositiveInt seed)
    {
        var page = (seed.Get % 3) + 1;
        var pageSize = (seed.Get % 10) + 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var query = new UserBoxQuery { Page = page, PageSize = pageSize };
        var result = service.GetUserBoxAsync(user.Id, query).GetAwaiter().GetResult();

        // Verify PagedResult structure
        return result != null &&
               result.List != null &&
               result.Total >= 0 &&
               result.Page == page &&
               result.PageSize == pageSize;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 6: API响应格式一致性**
    /// User orders API should return consistent PagedResult structure.
    /// **Validates: Requirements 10.2**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ApiResponseFormat_UserOrdersShouldHaveConsistentStructure(PositiveInt seed)
    {
        var page = (seed.Get % 3) + 1;
        var pageSize = (seed.Get % 10) + 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var query = new UserOrderQuery { Page = page, PageSize = pageSize };
        var result = service.GetUserOrdersAsync(user.Id, query).GetAwaiter().GetResult();

        // Verify PagedResult structure
        return result != null &&
               result.List != null &&
               result.Total >= 0 &&
               result.Page == page &&
               result.PageSize == pageSize;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 6: API响应格式一致性**
    /// Money detail API should return consistent PagedResult structure.
    /// **Validates: Requirements 10.3**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ApiResponseFormat_MoneyDetailShouldHaveConsistentStructure(PositiveInt seed)
    {
        var page = (seed.Get % 3) + 1;
        var pageSize = (seed.Get % 10) + 5;

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        // Create test user
        var user = CreateTestUser("TestUser");
        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        var query = new MoneyDetailQuery { Page = page, PageSize = pageSize };
        var result = service.GetUserMoneyDetailAsync(user.Id, query).GetAwaiter().GetResult();

        // Verify PagedResult structure
        return result != null &&
               result.List != null &&
               result.Total >= 0 &&
               result.Page == page &&
               result.PageSize == pageSize;
    }

    /// <summary>
    /// **Feature: user-management-frontend, Property 6: API响应格式一致性**
    /// Login stats API should return consistent LoginStatsResponse structure.
    /// **Validates: Requirements 10.6**
    /// </summary>
    [Property(MaxTest = 100)]
    public bool ApiResponseFormat_LoginStatsShouldHaveConsistentStructure(PositiveInt seed)
    {
        var types = new[] { "day", "week", "month" };
        var type = types[seed.Get % types.Length];

        using var dbContext = CreateDbContext();
        var service = new UserBusinessService(dbContext, _mockLogger.Object);

        var query = new LoginStatsQuery { Type = type };
        var result = service.GetLoginStatsAsync(query).GetAwaiter().GetResult();

        // Verify LoginStatsResponse structure
        return result != null &&
               result.Labels != null &&
               result.Values != null &&
               result.Labels.Count == result.Values.Count &&
               result.TotalLogins >= 0;
    }

    #endregion

    #region Helper Methods

    private HoneyBoxDbContext CreateDbContext()
    {
        var options = new DbContextOptionsBuilder<HoneyBoxDbContext>()
            .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
            .ConfigureWarnings(w => w.Ignore(InMemoryEventId.TransactionIgnoredWarning))
            .Options;

        return new HoneyBoxDbContext(options);
    }

    private User CreateTestUser(string nickname)
    {
        return new User
        {
            OpenId = Guid.NewGuid().ToString("N"),
            Uid = $"UID{DateTime.Now.Ticks}{Guid.NewGuid():N}".Substring(0, 20),
            Nickname = nickname,
            HeadImg = "https://example.com/avatar.png",
            Mobile = $"138{new Random().Next(10000000, 99999999)}",
            Money = 100,
            Integral = 50,
            Score = 30,
            Status = 1,
            IsTest = 0,
            Pid = 0,
            Vip = 1,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };
    }

    #endregion
}
