using Microsoft.Extensions.Logging;
using Service.AI;
using Service.Message;
using Service.Transaction;

namespace WebApi.Test.Budget;

public class BudgetStatsTest : BaseTest
{
    private readonly IBudgetRepository _budgetRepository = Substitute.For<IBudgetRepository>();
    private readonly IBudgetArchiveRepository _budgetArchiveRepository = Substitute.For<IBudgetArchiveRepository>();
    private readonly ITransactionRecordRepository _transactionsRepository = Substitute.For<ITransactionRecordRepository>();
    private readonly ITransactionStatisticsService _transactionStatisticsService = Substitute.For<ITransactionStatisticsService>();
    private readonly IOpenAiService _openAiService = Substitute.For<IOpenAiService>();
    private readonly IMessageService _messageService = Substitute.For<IMessageService>();
    private readonly ILogger<BudgetService> _logger = Substitute.For<ILogger<BudgetService>>();
    private readonly IBudgetSavingsService _budgetSavingsService = Substitute.For<IBudgetSavingsService>();
    private readonly IDateTimeProvider _dateTimeProvider = Substitute.For<IDateTimeProvider>();
    private readonly BudgetService _service;

    public BudgetStatsTest()
    {
        _dateTimeProvider.Now.Returns(new DateTime(2024, 1, 15));
        
        IBudgetStatsService budgetStatsService = new BudgetStatsService(
            _budgetRepository,
            _budgetArchiveRepository,
            _transactionStatisticsService,
            _dateTimeProvider,
            Substitute.For<ILogger<BudgetStatsService>>()
        );
        
        _service = new BudgetService(
            _budgetRepository,
            _budgetArchiveRepository,
            _transactionsRepository,
            _transactionStatisticsService,
            _openAiService,
            _messageService,
            _logger,
            _budgetSavingsService,
            _dateTimeProvider,
            budgetStatsService
        );
    }

    [Fact]
    public async Task GetCategoryStats_月度_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 1, 15);
        var budgets = new List<BudgetRecord>
        {
            new() { Id = 1, Name = "吃喝", Limit = 2000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "餐饮,零食" },
            new() { Id = 2, Name = "交通", Limit = 500, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "交通" }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>())
            .Returns(args =>
            {
                var b = (BudgetRecord)args[0];
                return b.Name == "吃喝" ? 1200m : 300m;
            });
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>(), Arg.Any<TransactionType>(), Arg.Any<List<string>>(), Arg.Any<bool>())
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 15), 1500m }  // 1月15日累计1500（吃喝1200+交通300）
            });

        // Act
        var result = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert
        result.Month.Limit.Should().Be(2500);  // 吃喝2000 + 交通500
        result.Month.Current.Should().Be(1500); // 吃喝1200 + 交通300
    }

    [Fact]
    public async Task GetCategoryStats_月度_硬性收支_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 1, 15);
        var budgets = new List<BudgetRecord>
        {
            new() { Id = 1, Name = "房租", Limit = 3100, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, IsMandatoryExpense = true }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>())
            .Returns(0m); // 实际支出的金额为0
        
        _dateTimeProvider.Now.Returns(referenceDate);
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>(), Arg.Any<TransactionType>(), Arg.Any<List<string>>(), Arg.Any<bool>())
            .Returns(new Dictionary<DateTime, decimal>());

        // Act
        var result = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert
        // 硬性预算的限额保持不变，不根据时间计算
        result.Month.Limit.Should().Be(3100);
        // 实际使用值根据时间计算：1月有31天，15号经过了15天
        // 3100 * 15 / 31 ≈ 1500
        result.Month.Current.Should().BeApproximately(1500, 1);
    }

    [Fact]
    public async Task GetCategoryStats_年度_1月_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 1, 15);
        var budgets = new List<BudgetRecord>
        {
            new() { Id = 2, Name = "月度吃饭", Limit = 3000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "餐饮" },
            new() { Id = 1, Name = "年度旅游", Limit = 12000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Year, SelectedCategories = "旅游" }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        
        // 月度统计使用趋势统计数据（只包含月度预算的分类）
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1 && d.Day == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1 && d.Day == 31),
            TransactionType.Expense,
            Arg.Is<List<string>>(list => list.Count == 1 && list.Contains("餐饮")))
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 15), 800m }  // 1月15日月度吃饭累计800
            });
        
        // 年度统计使用GetCurrentAmountAsync
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>())
            .Returns(args =>
            {
                var b = (BudgetRecord)args[0];
                var startDate = (DateTime)args[1];
                var endDate = (DateTime)args[2];
                
                // 月度范围查询 - 月度吃饭（1月）
                if (startDate.Month == 1 && startDate.Day == 1 && endDate.Month == 1)
                {
                    return b.Name == "月度吃饭" ? 800m : 0m;
                }
                
                // 年度范围查询 - 年度旅游
                if (startDate.Month == 1 && startDate.Day == 1 && endDate.Month == 12)
                {
                    return b.Name == "年度旅游" ? 2000m : 0m;
                }
                
                return 0m;
            });
        
        // 年度趋势统计（包含所有分类）
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1 && d.Day == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 12 && d.Day == 31),
            TransactionType.Expense,
            Arg.Is<List<string>>(list => list.Count == 2),  // 包含所有分类：餐饮、旅游
            true)
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 1), 2800m }  // 1月累计：月度吃饭800 + 年度旅游2000 = 2800
            });

        // Act
        var result = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert
        // 月度统计中：只包含月度预算
        result.Month.Limit.Should().Be(3000);       // 月度吃饭3000
        result.Month.Current.Should().Be(800);      // 月度吃饭已用800（从GetCurrentAmountAsync获取）
        result.Month.Count.Should().Be(1);          // 只包含1个月度预算
        
        // 年度统计中：包含所有预算（月度预算按剩余月份折算）
        // 1月时，月度预算分为：当前月(1月) + 剩余月份(2-12月共11个月)
        result.Year.Limit.Should().Be(12000 + (3000 * 12));  // 年度旅游12000 + 月度吃饭折算年度(3000*12=36000) = 48000
        result.Year.Current.Should().Be(2000 + 800);         // 年度旅游2000 + 月度吃饭800 = 2800
        result.Year.Count.Should().Be(3);                    // 包含3个预算项：年度旅游、月度吃饭(当前月)、月度吃饭(剩余11个月)
    }

    [Fact]
    public async Task GetCategoryStats_年度_1月_硬性收支_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 1, 1); // 元旦
        var budgets = new List<BudgetRecord>
        {
            new() { Id = 1, Name = "年度固定支出", Limit = 3660, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Year, IsMandatoryExpense = true }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>()).Returns(0m);
        _dateTimeProvider.Now.Returns(referenceDate);
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>(), Arg.Any<TransactionType>(), Arg.Any<List<string>>(), Arg.Any<bool>())
            .Returns(new Dictionary<DateTime, decimal>());

        // Act
        var result = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert
        // 硬性预算的限额保持不变
        result.Year.Limit.Should().Be(3660);
        // 实际使用值根据时间计算：2024是闰年，366天。1月1号是第1天。
        // 3660 * 1 / 366 ≈ 10
        result.Year.Current.Should().BeApproximately(10, 0.1m);
    }

    [Fact]
    public async Task GetCategoryStats_年度_3月_硬性收支_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 3, 31); // 3月最后一天
        var budgets = new List<BudgetRecord>
        {
            new() { Id = 1, Name = "年度固定支出", Limit = 3660, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Year, IsMandatoryExpense = true }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>()).Returns(0m);
        _dateTimeProvider.Now.Returns(referenceDate);
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>(), Arg.Any<TransactionType>(), Arg.Any<List<string>>(), Arg.Any<bool>())
            .Returns(new Dictionary<DateTime, decimal>());

        // Act
        var result = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert
        // 硬性预算的限额保持不变
        result.Year.Limit.Should().Be(3660);
        // 实际使用值根据时间计算：2024是闰年。1月(31) + 2月(29) + 3月(31) = 91天
        // 3660 * 91 / 366 ≈ 910
        result.Year.Current.Should().BeApproximately(910, 1);
    }

    [Fact]
    public async Task GetCategoryStats_月度_发生年度收支_Test()
    {
        // Arrange
        var referenceDate = new DateTime(2024, 1, 15);
        
        // 设置预算：包含月度预算和年度预算
        var budgets = new List<BudgetRecord>
        {
            // 月度预算：吃喝
            new() { Id = 1, Name = "吃喝", Limit = 2000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "餐饮,零食" },
            
            // 月度预算：交通
            new() { Id = 2, Name = "交通", Limit = 500, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "交通" },
            
            // 年度预算：年度旅游（当前月度发生了相关支出）
            new() { Id = 3, Name = "年度旅游", Limit = 12000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Year, SelectedCategories = "旅游,度假" },
            
            // 年度预算：年度奖金（当前月度发生了相关收入）
            new() { Id = 4, Name = "年度奖金", Limit = 50000, Category = BudgetCategory.Income, Type = BudgetPeriodType.Year, SelectedCategories = "奖金,年终奖" }
        };

        _budgetRepository.GetAllAsync().Returns(budgets);
        
        // 设置月度预算的当前金额
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>())
            .Returns(args =>
            {
                var b = (BudgetRecord)args[0];
                return b.Name switch
                {
                    "吃喝" => 1200m,      // 月度预算：已用1200元
                    "交通" => 300m,       // 月度预算：已用300元
                    "年度旅游" => 2000m,   // 年度预算：1月份已用2000元
                    "年度奖金" => 10000m,  // 年度预算：1月份已收10000元
                    _ => 0m
                };
            });
        
        // 设置月度趋势统计数据：只包含月度预算相关的分类（餐饮、零食、交通）
        // 注意：不应包含年度预算的分类（旅游、度假、奖金、年终奖）
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1),
            TransactionType.Expense,
            Arg.Is<List<string>>(list => list.Count == 3 && list.Contains("餐饮") && list.Contains("零食") && list.Contains("交通")))
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 15), 1500m }  // 1月15日累计1500（吃喝1200+交通300，不包含年度旅游2000）
            });
        
        // 设置年度趋势统计数据：包含所有预算相关的分类
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1 && d.Day == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 12 && d.Day == 31),
            TransactionType.Expense,
            Arg.Is<List<string>>(list => list.Count == 5),  // 餐饮、零食、交通、旅游、度假
            true)
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 1), 3500m }  // 1月累计3500（吃喝1200+交通300+年度旅游2000）
            });
        
        // 设置收入相关的趋势统计数据
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1),
            TransactionType.Income,
            Arg.Any<List<string>>())
            .Returns(new Dictionary<DateTime, decimal>());  // 月度收入为空
        
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 1 && d.Day == 1),
            Arg.Is<DateTime>(d => d.Year == 2024 && d.Month == 12 && d.Day == 31),
            TransactionType.Income,
            Arg.Any<List<string>>(),
            true)
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 1, 1), 10000m }  // 年度奖金10000
            });

        // Act - 测试支出统计
        var expenseResult = await _service.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);
        
        // Act - 测试收入统计
        var incomeResult = await _service.GetCategoryStatsAsync(BudgetCategory.Income, referenceDate);

        // Assert - 支出月度统计：只包含月度预算，不包含年度预算
        expenseResult.Month.Limit.Should().Be(2500);  // 吃喝2000 + 交通500
        expenseResult.Month.Current.Should().Be(1500); // 吃喝1200 + 交通300（不包含年度旅游2000）
        expenseResult.Month.Count.Should().Be(2);      // 只包含2个月度预算
        expenseResult.Month.Rate.Should().Be(1500m / 2500m * 100); // 60%

        // Assert - 支出年度统计：包含所有预算（月度+年度）
        // 1月时，月度预算分为：当前月(1月) + 剩余月份(2-12月共11个月)
        expenseResult.Year.Limit.Should().Be(12000 + (2500 * 12)); // 年度旅游12000 + 月度预算折算为年度(2500*12)
        expenseResult.Year.Current.Should().Be(3500);              // 吃喝1200 + 交通300 + 年度旅游2000
        expenseResult.Year.Count.Should().Be(5);                   // 包含5个预算项：年度旅游、吃喝(当前月)、交通(当前月)、吃喝(剩余11个月)、交通(剩余11个月)

        // Assert - 收入月度统计：只包含月度预算（这里没有月度收入预算，所以应该为0）
        incomeResult.Month.Limit.Should().Be(0);      // 没有月度收入预算
        incomeResult.Month.Current.Should().Be(0);    // 没有月度收入预算（不包含年度奖金10000）
        incomeResult.Month.Count.Should().Be(0);      // 没有月度收入预算

        // Assert - 收入年度统计：包含所有预算（只有年度收入预算）
        incomeResult.Year.Limit.Should().Be(50000);   // 年度奖金50000
        incomeResult.Year.Current.Should().Be(10000); // 年度奖金已收10000
        incomeResult.Year.Count.Should().Be(1);       // 包含1个年度收入预算
    }

        
    [Fact]
    public async Task GetCategoryStats_年度_3月_2月预算变更_Test()
    {
        // Arrange
        // 测试场景：2024年3月查看年度预算统计，其中2月份发生了预算变更（吃喝预算从2000增加到2500）
        var referenceDate = new DateTime(2024, 3, 15);
        
        // 设置当前时间，确保3月被认为是当前月份
        _dateTimeProvider.Now.Returns(new DateTime(2024, 3, 15));
        
        // 当前3月份有效的预算
        var currentBudgets = new List<BudgetRecord>
        {
            new() { Id = 1, Name = "吃喝", Limit = 2500, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "餐饮,零食" }, // 2月预算变更后
            new() { Id = 2, Name = "交通", Limit = 500, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "交通" },
            new() { Id = 3, Name = "年度旅游", Limit = 12000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Year, SelectedCategories = "旅游,度假" }
        };

        // 2月份的归档数据（预算变更前）
        var febArchive = new BudgetArchive
        {
            Year = 2024,
            Month = 2,
            Content = new[]
            {
                new BudgetArchiveContent
                {
                    Id = 1,
                    Name = "吃喝",
                    Limit = 2000,  // 2月份时预算还是2000
                    Actual = 1800,  // 2月份实际花费1800
                    Category = BudgetCategory.Expense,
                    Type = BudgetPeriodType.Month,
                    SelectedCategories = new[] { "餐饮", "零食" }
                },
                new BudgetArchiveContent
                {
                    Id = 2,
                    Name = "交通",
                    Limit = 500,
                    Actual = 300,
                    Category = BudgetCategory.Expense,
                    Type = BudgetPeriodType.Month,
                    SelectedCategories = new[] { "交通" }
                }
            }
        };

        // 1月份的归档数据
        var janArchive = new BudgetArchive
        {
            Year = 2024,
            Month = 1,
            Content = new[]
            {
                new BudgetArchiveContent
                {
                    Id = 1,
                    Name = "吃喝",
                    Limit = 2000,  // 1月份预算也是2000
                    Actual = 1500,  // 1月份实际花费1500
                    Category = BudgetCategory.Expense,
                    Type = BudgetPeriodType.Month,
                    SelectedCategories = new[] { "餐饮", "零食" }
                },
                new BudgetArchiveContent
                {
                    Id = 2,
                    Name = "交通",
                    Limit = 500,
                    Actual = 250,
                    Category = BudgetCategory.Expense,
                    Type = BudgetPeriodType.Month,
                    SelectedCategories = new[] { "交通" }
                }
            }
        };

        // 设置仓储响应
        _budgetRepository.GetAllAsync().Returns(currentBudgets);
        
        // 设置归档仓储响应
        _budgetArchiveRepository.GetArchiveAsync(2024, 2).Returns(febArchive);
        _budgetArchiveRepository.GetArchiveAsync(2024, 1).Returns(janArchive);
        
        // 设置月度预算的当前金额查询（仅用于3月份）
        _budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Is<DateTime>(d => d.Month == 3), Arg.Is<DateTime>(d => d.Month == 3))
            .Returns(args =>
            {
                var b = (BudgetRecord)args[0];
                return b.Name switch
                {
                    "吃喝" => 800m,   // 3月份已花费800
                    "交通" => 200m,   // 3月份已花费200
                    _ => 0m
                };
            });
        
        // 年度旅游的年度金额查询
        _budgetRepository.GetCurrentAmountAsync(
            Arg.Is<BudgetRecord>(b => b.Id == 3), 
            Arg.Is<DateTime>(d => d.Month == 1), 
            Arg.Is<DateTime>(d => d.Month == 12))
            .Returns(2500m);  // 年度旅游1-3月已花费2500

        // 设置趋势统计数据查询（用于月度统计）
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Month == 3),
            Arg.Is<DateTime>(d => d.Month == 3),
            Arg.Any<TransactionType>(),
            Arg.Any<List<string>>(),
            Arg.Any<bool>())
            .Returns(new Dictionary<DateTime, decimal>
            {
                { new DateTime(2024, 3, 15), 1000m }  // 3月15日累计1000（吃喝800+交通200）
            });

        // 年度趋势统计数据查询
        // 注意：年度统计使用GetFilteredTrendStatisticsAsync获取趋势数据
        // 需要返回所有分类的累计金额，包括年度旅游的2500
        _transactionStatisticsService.GetFilteredTrendStatisticsAsync(
            Arg.Is<DateTime>(d => d.Month == 1),
            Arg.Is<DateTime>(d => d.Month == 12),
            Arg.Any<TransactionType>(),
            Arg.Any<List<string>>(),
            Arg.Is<bool>(b => b == true))
            .Returns(new Dictionary<DateTime, decimal>
            {
                // 3月累计：月度预算1000 + 年度旅游2500 = 3500
                { new DateTime(2024, 3, 1), 3500m }
            });
        
        // 补充：年度旅游的GetCurrentAmountAsync调用（用于计算Current）
        _budgetRepository.GetCurrentAmountAsync(
            Arg.Is<BudgetRecord>(b => b.Id == 3), 
            Arg.Is<DateTime>(d => d.Month == 1), 
            Arg.Is<DateTime>(d => d.Month == 12))
            .Returns(2500m);  // 年度旅游1-3月已花费2500

        // Act
        // 直接测试BudgetStatsService，而不是通过BudgetService
        var budgetStatsService = new BudgetStatsService(
            _budgetRepository,
            _budgetArchiveRepository,
            _transactionStatisticsService,
            _dateTimeProvider,
            Substitute.For<ILogger<BudgetStatsService>>()
        );
        
        var result = await budgetStatsService.GetCategoryStatsAsync(BudgetCategory.Expense, referenceDate);

        // Assert - 月度统计（3月份）
        // 月度统计应该只包含月度预算，使用当前预算限额
        result.Month.Limit.Should().Be(3000);  // 吃喝2500 + 交通500（使用变更后的预算）
        result.Month.Current.Should().Be(1000); // 吃喝800 + 交通200
        result.Month.Count.Should().Be(2);      // 包含2个月度预算
        
        // Assert - 年度统计（需要考虑预算变更和剩余月份）
        // 新逻辑：
        // 1. 对于归档数据，直接使用归档的限额，不折算
        // 2. 对于当前及未来月份，使用当前预算 × 剩余月份
        //
        // 预期年度限额计算：
        // 1月归档：吃喝2000 + 交通500 = 2500
        // 2月归档：吃喝2000 + 交通500 = 2500
        // 3-12月剩余（12 - 3 + 1 = 10个月）：吃喝2500×10 + 交通500×10 = 30000
        // 年度旅游：12000
        // 总计：2500 + 2500 + 30000 + 12000 = 47000
        result.Year.Limit.Should().Be(47000);
        
        // 预期年度实际金额：
        // 根据趋势统计数据，3月累计: 月度预算1000 + 年度旅游2500 = 3500
        // 但业务代码会累加所有预算项的Current值：
        // - 1月归档吃喝：1500
        // - 1月归档交通：250
        // - 2月归档吃喝：1800
        // - 2月归档交通：300
        // - 3月吃喝：800
        // - 3月交通：200
        // - 年度旅游：2500
        // 总计：1500+250+1800+300+800+200+2500 = 7350
        result.Year.Current.Should().Be(7350);
        
        // 应该包含：
        // - 1月归档的月度预算：吃喝、1个
        // - 1月归档的月度预算：交通、1个  
        // - 2月归档的月度预算：吃喝、1个
        // - 2月归档的月度预算：交通、1个
        // - 3月当前月的月度预算：吃喝、1个
        // - 3月当前月的月度预算：交通、1个
        // - 4-12月未来月的月度预算：吃喝、1个（RemainingMonths=9）
        // - 4-12月未来月的月度预算：交通、1个（RemainingMonths=9）
        // - 年度旅游：1个
        // 总计：9个
        result.Year.Count.Should().Be(9);
        
        // 验证使用率计算正确
        result.Month.Rate.Should().BeApproximately(1000m / 3000m * 100, 0.01m);
        // 年度使用率：7350 / 47000 * 100 = 15.64%
        result.Year.Rate.Should().BeApproximately(7350m / 47000m * 100, 0.01m);
    }
}