namespace Repository;

public interface IBudgetRepository : IBaseRepository<BudgetRecord>
{
    Task<decimal> GetCurrentAmountAsync(BudgetRecord budget, DateTime startDate, DateTime endDate);
    
    Task UpdateBudgetCategoryNameAsync(string oldName, string newName, TransactionType type);
}

public class BudgetRepository(IFreeSql freeSql) : BaseRepository<BudgetRecord>(freeSql), IBudgetRepository
{
    public async Task<decimal> GetCurrentAmountAsync(BudgetRecord budget, DateTime startDate, DateTime endDate)
    {
        var query = FreeSql.Select<TransactionRecord>()
            .Where(t => t.OccurredAt >= startDate && t.OccurredAt <= endDate);

        if (!string.IsNullOrEmpty(budget.SelectedCategories))
        {
            var categoryList = budget.SelectedCategories.Split(',');
            query = query.Where(t => categoryList.Contains(t.Classify));
        }

        if (budget.Category == BudgetCategory.Expense)
        {
            query = query.Where(t => t.Type == TransactionType.Expense);
        }
        else if (budget.Category == BudgetCategory.Income)
        {
            query = query.Where(t => t.Type == TransactionType.Income);
        }
        else if (budget.Category == BudgetCategory.Savings)
        {
            query = query.Where(t => t.Type == TransactionType.None);
        }

        return await query.SumAsync(t => t.Amount);
    }

    public async Task UpdateBudgetCategoryNameAsync(string oldName, string newName, TransactionType type)
    {
        var records = await FreeSql.Select<BudgetRecord>()
            .Where(b => b.SelectedCategories.Contains(oldName) && 
                        ((type == TransactionType.Expense && b.Category == BudgetCategory.Expense) ||
                         (type == TransactionType.Income && b.Category == BudgetCategory.Income) ||
                         (type == TransactionType.None && b.Category == BudgetCategory.Savings)))
            .ToListAsync();

        foreach (var record in records)
        {
            var categories = record.SelectedCategories.Split(',').ToList();
            for (int i = 0; i < categories.Count; i++)
            {
                if (categories[i] == oldName)
                {
                    categories[i] = newName;
                }
            }
            record.SelectedCategories = string.Join(',', categories);
        }

        await FreeSql.Update<BudgetRecord>()
            .SetSource(records)
            .ExecuteAffrowsAsync();
    }
}
