using System.Linq.Expressions;
namespace DigitalData.EmailProfiler.Application.Interfaces.Repositories;
///
/// Base repository interface for common CRUD operations with AutoMapper support.
/// Changes are automatically saved after each operation - no explicit SaveChanges needed.
///
/// Entity type
public interface IRepository where TEntity : class
{
// ==================== QUERY OPERATIONS ====================
Task GetByIdAsync(int id, CancellationToken cancellationToken = default);
Task> GetAllAsync(CancellationToken cancellationToken = default);
Task> FindAsync(Expression> predicate, CancellationToken cancellationToken = default);
Task FirstOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default);
Task ExistsAsync(Expression> predicate, CancellationToken cancellationToken = default);
Task CountAsync(Expression>? predicate = null, CancellationToken cancellationToken = default);
// ==================== CREATE OPERATIONS ====================
///
/// Create entity from DTO using AutoMapper and save immediately.
///
/// Created entity with ID populated
Task CreateAsync(TDto dto, CancellationToken cancellationToken = default) where TDto : class;
// ==================== UPDATE OPERATIONS ====================
///
/// Update ALL entities matching expression using DTO via AutoMapper.
/// WARNING: This can update multiple records. Use UpdateSingleAsync for single-record updates.
///
/// Number of entities updated
Task UpdateAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class;
///
/// Update SINGLE entity matching expression using DTO via AutoMapper.
/// SAFETY: Throws exception if zero or multiple entities match the predicate.
///
/// Thrown when zero or multiple entities match
Task UpdateSingleAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class;
// ==================== DELETE OPERATIONS ====================
///
/// Delete ALL entities matching expression.
/// WARNING: This can delete multiple records. Use DeleteSingleAsync for single-record deletes.
///
/// Number of entities deleted
Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default);
///
/// Delete SINGLE entity matching expression.
/// SAFETY: Throws exception if zero or multiple entities match the predicate.
///
/// Thrown when zero or multiple entities match
Task DeleteSingleAsync(Expression> predicate, CancellationToken cancellationToken = default);
}