namespace Repository;

/// <summary>
/// 仓储基础接口
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public interface IBaseRepository<T> where T : BaseEntity
{
    /// <summary>
    /// 获取所有数据
    /// </summary>
    Task<IEnumerable<T>> GetAllAsync();

    /// <summary>
    /// 根据ID获取单条数据
    /// </summary>
    Task<T?> GetByIdAsync(long id);

    /// <summary>
    /// 根据ID获取单条数据
    /// </summary>
    Task<T[]> GetByIdsAsync(long[] ids);

    /// <summary>
    /// 添加数据
    /// </summary>
    Task<bool> AddAsync(T entity);
    
    /// <summary>
    /// 添加数据
    /// </summary>
    Task<bool> AddRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 更新数据
    /// </summary>
    Task<bool> UpdateAsync(T entity);

    /// <summary>
    /// 批量更新数据
    /// </summary>
    Task<bool> UpdateRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 删除数据
    /// </summary>
    Task<bool> DeleteAsync(long id);
}


/// <summary>
/// 仓储基类实现 - 基于 FreeSql
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public abstract class BaseRepository<T>(IFreeSql freeSql) : IBaseRepository<T> where T : BaseEntity
{
    protected readonly IFreeSql FreeSql = freeSql ?? throw new ArgumentNullException(nameof(freeSql));

    public virtual async Task<IEnumerable<T>> GetAllAsync()
    {
        try
        {
            return await FreeSql.Select<T>().ToListAsync();
        }
        catch
        {
            return [];
        }
    }

    public virtual async Task<T?> GetByIdAsync(long id)
    {
        try
        {
            // FreeSql 会根据配置自动识别主键
            return await FreeSql.Select<T>().Where(x => x.Id == id).FirstAsync();
        }
        catch
        {
            return null;
        }
    }

    public virtual async Task<T[]> GetByIdsAsync(long[] ids)
    {
        try
        {
            var result = await FreeSql.Select<T>().Where(x => ids.Contains(x.Id)).ToListAsync();
            return result.ToArray();
        }
        catch
        {
            return [];
        }
    }

    public virtual async Task<bool> AddAsync(T entity)
    {
        try
        {
            var result = await FreeSql.Insert(entity).ExecuteAffrowsAsync();
            return result == 1;
        }
        catch
        {
            return false;
        }
    }

    public async Task<bool> AddRangeAsync(IEnumerable<T> entities)
    {
        var result = await FreeSql.Insert(entities).ExecuteAffrowsAsync();
        return result == entities.Count();
    }

    public virtual async Task<bool> UpdateAsync(T entity)
    {
        try
        {
            var affrows = await FreeSql.Update<T>()
                .SetSource(entity)
                .ExecuteAffrowsAsync();
            return affrows > 0;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Update failed: {ex.Message}");
            return false;
        }
    }

    public virtual async Task<bool> UpdateRangeAsync(IEnumerable<T> entities)
    {
        try
        {
            var affrows = await FreeSql.Update<T>()
                .SetSource(entities)
                .ExecuteAffrowsAsync();
            return affrows == entities.Count();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"UpdateRange failed: {ex.Message}");
            return false;
        }
    }

    public virtual async Task<bool> DeleteAsync(long id)
    {
        try
        {
            var affrows = await FreeSql.Delete<T>().Where(x => x.Id == id).ExecuteAffrowsAsync();
            return affrows > 0;
        }
        catch
        {
            return false;
        }
    }
}
