namespace Repository;

/// <summary>
/// 周期性账单仓储接口
/// </summary>
public interface ITransactionPeriodicRepository : IBaseRepository<TransactionPeriodic>
{
    /// <summary>
    /// 获取分页列表
    /// </summary>
    Task<IEnumerable<TransactionPeriodic>> GetPagedListAsync(int pageIndex, int pageSize, string? searchKeyword = null);

    /// <summary>
    /// 获取总数
    /// </summary>
    Task<long> GetTotalCountAsync(string? searchKeyword = null);

    /// <summary>
    /// 获取需要执行的周期性账单（包含今天应该执行的）
    /// </summary>
    Task<IEnumerable<TransactionPeriodic>> GetPendingPeriodicBillsAsync();

    /// <summary>
    /// 更新执行时间
    /// </summary>
    Task<bool> UpdateExecuteTimeAsync(long id, DateTime lastExecuteTime, DateTime? nextExecuteTime);
}

/// <summary>
/// 周期性账单仓储实现
/// </summary>
public class TransactionPeriodicRepository(IFreeSql freeSql) 
    : BaseRepository<TransactionPeriodic>(freeSql), ITransactionPeriodicRepository
{
    public async Task<IEnumerable<TransactionPeriodic>> GetPagedListAsync(
        int pageIndex, 
        int pageSize, 
        string? searchKeyword = null)
    {
        var query = FreeSql.Select<TransactionPeriodic>();

        // 搜索关键词
        if (!string.IsNullOrWhiteSpace(searchKeyword))
        {
            query = query.Where(x => 
                x.Reason.Contains(searchKeyword) || 
                x.Classify.Contains(searchKeyword));
        }

        return await query
            .OrderByDescending(x => x.CreateTime)
            .Skip((pageIndex - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    public async Task<long> GetTotalCountAsync(string? searchKeyword = null)
    {
        var query = FreeSql.Select<TransactionPeriodic>();

        if (!string.IsNullOrWhiteSpace(searchKeyword))
        {
            query = query.Where(x => 
                x.Reason.Contains(searchKeyword) || 
                x.Classify.Contains(searchKeyword));
        }

        return await query.CountAsync();
    }

    public async Task<IEnumerable<TransactionPeriodic>> GetPendingPeriodicBillsAsync()
    {
        var now = DateTime.Now;
        return await FreeSql.Select<TransactionPeriodic>()
            .Where(x => x.IsEnabled)
            .Where(x => x.NextExecuteTime == null || x.NextExecuteTime <= now)
            .ToListAsync();
    }

    public async Task<bool> UpdateExecuteTimeAsync(long id, DateTime lastExecuteTime, DateTime? nextExecuteTime)
    {
        try
        {
            var result = await FreeSql.Update<TransactionPeriodic>()
                .Set(x => x.LastExecuteTime, lastExecuteTime)
                .Set(x => x.NextExecuteTime, nextExecuteTime)
                .Set(x => x.UpdateTime, DateTime.Now)
                .Where(x => x.Id == id)
                .ExecuteAffrowsAsync();
            return result == 1;
        }
        catch
        {
            return false;
        }
    }
}
