using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using XF.Domain.Entities;

namespace XF.Domain.Repository
{
    public interface IRepositorySqlSugar<TEntity, TKey> : IRepositoryWithTKey<TEntity, string>
        where TEntity : class, IEntity<string>, new()
    {
        Task<(int Total, List<TEntity> Items)> QueryPagedAsync(
            Expression<Func<TEntity, bool>> predicate,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> orderByCreator,
            int pageIndex,
            int pageSize,
            bool permissionVerify = false,
            params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs);

        Task<(int Total, List<TEntity> Items)> QueryPagedAsync(Expression<Func<TEntity, bool>> predicate,
            int pageIndex,
            int pageSize,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? includes = null,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? orderByCreator = null,
            bool permissionVerify = false,
            params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs);

        Task<List<TEntity>> QueryExtAsync(
            Expression<Func<TEntity, bool>> predicate,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? includes = null,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? orderByCreator = null,
            bool permissionVerify = false,
            params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs);

        Task<List<TEntity>> QueryExtAsync(
            Expression<Func<TEntity, bool>> predicate,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes,
            bool permissionVerify = false);

        Task<TEntity> GetExtAsync(
            Expression<Func<TEntity, bool>> predicate,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes,
            bool permissionVerify = false);

        Task<TEntity> GetExtAsync(
            TKey id,
            Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes,
            bool permissionVerify = false);

        TEntity Get(TKey id);

        TEntity Get(Expression<Func<TEntity, bool>> predicate);


        Task UpdateAsync(TEntity entity, bool ignoreNullColumns = true, CancellationToken cancellationToken = default);

        ISugarQueryable<TEntity> Queryable(bool permissionVerify = false, bool includeDeleted = false);
        IUpdateable<TEntity> Updateable();
        IUpdateable<TEntity> Updateable(TEntity entity);
        IUpdateable<TEntity> Updateable(List<TEntity> entities);
        IDeleteable<TEntity> Removeable();

        UpdateNavTaskInit<TEntity, TEntity> UpdateNav(TEntity entity);
        UpdateNavTaskInit<TEntity, TEntity> UpdateNav(TEntity entity, UpdateNavRootOptions options);
        UpdateNavTaskInit<TEntity, TEntity> UpdateNav(List<TEntity> entities);
        UpdateNavTaskInit<TEntity, TEntity> UpdateNav(List<TEntity> entities, UpdateNavRootOptions options);

        /// <summary>
        /// 未实现统一为子表赋值creatorId, creatorOrg等字段，插入前需手动赋值
        /// </summary>
        InsertNavTaskInit<TEntity, TEntity> AddNav(TEntity entity);
        InsertNavTaskInit<TEntity, TEntity> AddNav(TEntity entity, InsertNavRootOptions options);

        /// <summary>
        /// 未实现统一为子表赋值creatorId, creatorOrg等字段，插入前需手动赋值
        /// </summary>
        InsertNavTaskInit<TEntity, TEntity> AddNav(List<TEntity> entities);
        InsertNavTaskInit<TEntity, TEntity> AddNav(List<TEntity> entities, InsertNavRootOptions options);

        DeleteNavTaskInit<TEntity, TEntity> RemoveNav(TEntity entity);
        DeleteNavTaskInit<TEntity, TEntity> RemoveNav(List<TEntity> entities);
        DeleteNavTaskInit<TEntity, TEntity> RemoveNav(Expression<Func<TEntity, bool>> predicate);

        ISugarQueryable<TEntity> UnionAll(params ISugarQueryable<TEntity>[] queryables);
    }

    public interface IRepositorySqlSugar<TEntity> : IRepositorySqlSugar<TEntity, string>
        where TEntity : class, IEntity<string>, new()
    {

    }
}
