using System.Linq.Expressions;

namespace DramaLing.Api.Repositories;

/// <summary>
/// 泛型 Repository 介面，提供基本的 CRUD 操作
/// </summary>
/// <typeparam name="T">實體類型</typeparam>
public interface IRepository<T> where T : class
{
    // 查詢操作
    Task<T?> GetByIdAsync(object id);
    Task<IEnumerable<T>> GetAllAsync();
    Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate);
    Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate);
    Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate);
    Task<int> CountAsync(Expression<Func<T, bool>>? predicate = null);

    // 分頁查詢
    Task<(IEnumerable<T> Items, int TotalCount)> GetPagedAsync(
        int pageNumber,
        int pageSize,
        Expression<Func<T, bool>>? filter = null,
        Func<IQueryable<T>, IOrderedQueryable<T>>? orderBy = null);

    // 修改操作
    Task<T> AddAsync(T entity);
    Task<IEnumerable<T>> AddRangeAsync(IEnumerable<T> entities);
    Task UpdateAsync(T entity);
    Task UpdateRangeAsync(IEnumerable<T> entities);
    Task DeleteAsync(T entity);
    Task DeleteAsync(object id);
    Task DeleteRangeAsync(IEnumerable<T> entities);

    // 工作單元
    Task<int> SaveChangesAsync();
}