using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace MadRunFabric.Common
{
    public interface IRepository<T, TKey> where T : class, IBaseModel<TKey>
    {


        /// <summary>
        /// 获取查询的数量
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>e
        Task<long> Count(Expression<Func<T, bool>> @where = null);


        /// <summary>
        /// 根据Key查询第一条 （默认id）
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<T> GetSingle(TKey key);

        /// <summary>
        /// 根据查询条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<T> GetSingle(Expression<Func<T, bool>> @where = null);

        /// <summary>
        /// 查询一条数据 条件 排序
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<T> GetSingle(Expression<Func<T, bool>> @where = null,SortDefinition<T> sort = null);

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<IEnumerable<T>> Get(Expression<Func<T, bool>> @where = null);

        /// <summary>
        /// 查询数据列表 包含查询条件，显示字段，排序
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="field"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        Task<IEnumerable<T>> Get(FilterDefinition<T> filter, string[] field = null, SortDefinition<T> sort = null);

        /// <summary>
        /// 根据分页查询数据列表 包含查询条件，显示字段，排序
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        Task<IEnumerable<T>> GetByPage(FilterDefinition<T> filter, int pageIndex, int pageSize, SortDefinition<T> sort = null);




        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<T>> GetAll();



        /// <summary>
        /// 添加一項
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> Add(T entity);

        /// <summary>
        /// 添加多項 （多条数据务必如此）
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        Task<bool> AddRange(List<T> entitys);

        /// <summary>
        /// 根据key删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<bool> Remove(TKey key);

        /// <summary>
        /// 根据表达式删除
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<bool> Remove(Expression<Func<T, bool>> @where=null);

        /// <summary>
        /// 删除所有
        /// </summary>
        /// <returns></returns>
        Task<bool> RemoveAll();

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> Update(T entity);

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dic">要修改的字段</param>
        /// <returns></returns>
        Task<bool> Update(string id, Dictionary<object, object> dic);

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> UpdateOne(T entity);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        Task<bool> UpdateManay(T entity, Dictionary<string, string> dic, FilterDefinition<T> filter = null);

        /// <summary>
        /// 异步根据条件获取总数
        /// </summary>
        /// <param name="filter">条件</param>
        /// <returns></returns>
        Task<long> CountAsync(FilterDefinition<T> filter);

        /// <summary>
        /// 添加一項
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<string> AddRetID(T entity);
    }
}
