namespace WebApi.Test.Repository;

public class TransactionRecordRepositoryTest : TransactionTestBase
{
    private readonly ITransactionRecordRepository _repository;

    public TransactionRecordRepositoryTest()
    {
        _repository = new TransactionRecordRepository(FreeSql);
    }

    [Fact]
    public async Task AddAsync_添加记录_Test()
    {
        var record = CreateTestRecord(-100);
        var result = await _repository.AddAsync(record);
        result.Should().BeTrue();

        var dbRecord = await _repository.GetByIdAsync(record.Id);
        dbRecord.Should().NotBeNull();
        dbRecord.Amount.Should().Be(-100);
    }

    [Fact]
    public async Task QueryAsync_按类型筛选_Test()
    {
        await _repository.AddAsync(CreateExpense(100));
        await _repository.AddAsync(CreateIncome(200));

        var expenses = await _repository.QueryAsync(type: TransactionType.Expense);
        expenses.Should().HaveCount(1);
        expenses.First().Amount.Should().Be(-100);

        var incomes = await _repository.QueryAsync(type: TransactionType.Income);
        incomes.Should().HaveCount(1);
        incomes.First().Amount.Should().Be(200);
    }

    [Fact]
    public async Task QueryAsync_按通过时间范围筛选_Test()
    {
        await _repository.AddAsync(CreateExpense(100, new DateTime(2023, 1, 1)));
        await _repository.AddAsync(CreateExpense(100, new DateTime(2023, 2, 1)));
        await _repository.AddAsync(CreateExpense(100, new DateTime(2023, 3, 1)));

        // 查询 1月到2月
        var results = await _repository.QueryAsync(
            startDate: new DateTime(2023, 1, 1),
            endDate: new DateTime(2023, 2, 28)); // Include Feb
        
        results.Should().HaveCount(2);
    }

     [Fact]
    public async Task QueryAsync_按年月筛选_Test()
    {
        await _repository.AddAsync(CreateExpense(100, new DateTime(2023, 1, 15)));
        await _repository.AddAsync(CreateExpense(100, new DateTime(2023, 2, 15)));

        var results = await _repository.QueryAsync(year: 2023, month: 1);
        results.Should().HaveCount(1);
        results.First().OccurredAt.Month.Should().Be(1);
    }

    [Fact]
    public async Task CountAsync_统计数量_Test()
    {
        await _repository.AddAsync(CreateExpense(100));
        await _repository.AddAsync(CreateExpense(200));
        await _repository.AddAsync(CreateIncome(3000));

        var count = await _repository.CountAsync(type: TransactionType.Expense);
        count.Should().Be(2);
    }

    [Fact]
    public async Task GetDistinctClassifyAsync_获取去重分类_Test()
    {
        await _repository.AddAsync(CreateExpense(100, classify: "餐饮"));
        await _repository.AddAsync(CreateExpense(100, classify: "餐饮"));
        await _repository.AddAsync(CreateExpense(100, classify: "交通"));

        var classifies = await _repository.GetDistinctClassifyAsync();
        classifies.Should().HaveCount(2);
        classifies.Should().Contain("餐饮");
        classifies.Should().Contain("交通");
    }

    [Fact]
    public async Task BatchUpdateByReasonAsync_批量更新_Test()
    {
        await _repository.AddAsync(CreateExpense(100, reason: "麦当劳", classify: "餐饮"));
        await _repository.AddAsync(CreateExpense(100, reason: "麦当劳", classify: "餐饮"));
        await _repository.AddAsync(CreateExpense(100, reason: "肯德基", classify: "餐饮"));

        // 将所有"麦当劳"改为"快餐"分类，类型保持支出
        var count = await _repository.BatchUpdateByReasonAsync("麦当劳", TransactionType.Expense, "快餐");
        count.Should().Be(2);

        var records = await _repository.QueryAsync(reason: "麦当劳");
        records.All(r => r.Classify == "快餐").Should().BeTrue();
        
        var kfc = await _repository.QueryAsync(reason: "肯德基");
        kfc.First().Classify.Should().Be("餐饮");
    }
}
