using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SqlSugar;
using WMS.Entity;
using WMS.Entity.Context;
using WMS.IDAL;

namespace WMS.DAL
{
    public class BaseRepository<T> : IBaseRepository<T> where T : BaseEntity, new()
    {
        private readonly SqlSugarScope _db;

        public BaseRepository(SqlSugarScope db)
        {
            _db = db;
        }
        public int Add(T t)
        {
            return _db.Insertable(t).ExecuteCommand();
        }
        public async Task<int> AddAsync(T t)
        {
            return await _db.Insertable(t).ExecuteCommandAsync();
        }

        public int Edit(T t)
        {
            return _db.Updateable(t).IgnoreColumns(m => new { m.CreateTime,m.CreateUser}).ExecuteCommand();
        }
        public async Task<int> EditAsync(T t)
        {
            return await _db.Updateable(t).IgnoreColumns(m => new { m.CreateTime, m.CreateUser }).ExecuteCommandAsync();
        }

        public int Remove(int id,int userId = 0)
        {
            var data = GetOneById(id);
            data.IsDel = "1";
            data.UpdateTime = DateTime.Now;
            data.UpdateUser = userId;
            return _db.Updateable(data).UpdateColumns(m => new { m.IsDel }).ExecuteCommand();
        }
        public async Task<int> RemoveAsync(int id,int userId = 0)
        {
            var data = await GetOneByIdAsync(id);
            data.IsDel = "1";
            data.UpdateTime = DateTime.Now;
            data.UpdateUser = userId;
            return await _db.Updateable(data).UpdateColumns(m => new { m.IsDel }).ExecuteCommandAsync();
        }

        public int Remove(T t, int userId = 0)
        {
            t.IsDel = "1";
            t.UpdateTime = DateTime.Now;
            t.UpdateUser = userId;
            return  _db.Updateable(t).UpdateColumns(m => new { m.IsDel }).ExecuteCommand();
        }
        public async Task<int> RemoveAsync(T t,int userId = 0)
        {
            t.IsDel = "1";
            t.UpdateTime = DateTime.Now;
            t.UpdateUser = userId;
            return await _db.Updateable(t).UpdateColumns(m => new { m.IsDel }).ExecuteCommandAsync();
        }
        public int RemoveAll(List<T> t,int userId = 0)
        {
            foreach (var item in t)
            {
                item.IsDel = "1";
                item.UpdateTime = DateTime.Now;
                item.UpdateUser = userId;
            }
            
            return _db.Updateable(t).UpdateColumns(m => new { m.IsDel }).ExecuteCommand();
        }
        public async Task<int> RemoveAllAsync(List<T> t,int userId = 0)
        {
            foreach (var item in t)
            {
                item.IsDel = "1";
                item.UpdateTime = DateTime.Now;
                item.UpdateUser = userId;
            }

            return await _db.Updateable(t).UpdateColumns(m => new { m.IsDel }).ExecuteCommandAsync();
        }
        public void Save()
        {
            _db.SaveQueues();
        }
        public async Task SaveAsync()
        {
            await _db.SaveQueuesAsync();
        }

        public T GetOneById(int id)
        {
            var data = _db.Queryable<T>().First(m => m.Id == id && m.IsDel == "0");
            return data;
        }
        public async Task<T> GetOneByIdAsync(int id)
        {
            var data = await _db.Queryable<T>().FirstAsync(m => m.Id == id && m.IsDel == "0");
            return data;
        }

        public List<T> GetModels(string sqlString) 
        {
            var models = _db.Ado.SqlQuery<T>(sqlString);
            return models;
        }

        public T GetModel(string sqlString)
        {
            var model = _db.Ado.SqlQuery<T>(sqlString);
            return model.FirstOrDefault();
        }
        
        public SqlSugar.ISugarQueryable<T> GetAllAsync()
        {
            var data =_db.Queryable<T>().Where(m=>m.IsDel =="0");
            return data;
        }
        public SqlSugar.ISugarQueryable<T> GetAllWhereAsync(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            var data = GetAllAsync().Where(predicate);
            return data;
        }
        public SqlSugar.ISugarQueryable<T> GetAllByOrderAsync(System.Linq.Expressions.Expression<Func<T, bool>> predicate, bool asc = true)
        {
            var type = OrderByType.Asc;
            if (!asc)
            {
                type = OrderByType.Desc;
            }
            var data = GetAllWhereAsync(predicate).OrderBy(m => m.CreateTime, type);
            return data;
        }
        public SqlSugar.ISugarQueryable<T> GeTAllByPageAsync(System.Linq.Expressions.Expression<Func<T, bool>> predicate, int pageSize, int pageIndex,out int count )
        {
            var list = GetAllWhereAsync(predicate);
            count = list.Count();
            var data = list.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
            return data;
        }

        public SqlSugar.ISugarQueryable<T> GetAllByOrderPageAsync(System.Linq.Expressions.Expression<Func<T, bool>> predicate, int pageSize, int pageIndex, out int count , bool asc = true)
        {
            var list = GetAllByOrderAsync(predicate, asc);
            count = list.Count();
            var data = list.Skip(pageSize * (pageIndex-1)).Take(pageSize);

            return data;
        }
        
    }
}