using Hushian.Application.Contracts.Persistence;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;

namespace Hushian.Persistence.Repositories
{
    public class GenericRepository<T> : IGenericRepository<T> where T : class
    {
        private readonly HushianDbContext _context;
        private readonly DbSet<T> _query;

        public GenericRepository(HushianDbContext context)
        {
            _context = context;
            _query = _context.Set<T>();
        }
        public async Task<T?> ADD(T entity)
        {
            try
            {
                await _context.AddAsync(entity);
                if ((await _context.SaveChangesAsync() >= 1))
                    return entity;

                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        public async Task<bool> ADDBool(T entity)
        {
            await _context.AddAsync(entity);
            return (await _context.SaveChangesAsync() == 1);
        }
        public async Task<ICollection<T>> ADD(ICollection<T> entities)
        {
            try
            {
                await _context.AddRangeAsync(entities);
                if ((await _context.SaveChangesAsync() == entities.Count()))
                    return entities;

                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        public async Task<T?> UPDATE(T entity)
        {
            try
            {
                _context.Entry(entity).State = EntityState.Modified;
                if ((await _context.SaveChangesAsync() == 1))
                    return entity;
                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        public async Task<bool> UPDATEBool(T entity)
        {
            _context.Entry(entity).State = EntityState.Modified;
            return (await _context.SaveChangesAsync() == 1);
        }
        public async Task<ICollection<T>> UPDATE(ICollection<T> entities)
        {
            try
            {
                foreach (var entity in entities)
                    _context.Entry(entity).State = EntityState.Modified;

                if ((await _context.SaveChangesAsync()) == entities.Count())
                    return entities;
                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }
        public async Task<bool> DELETE(T entity)
        {
            try
            {
                _context.Set<T>().Remove(entity);
                return (await _context.SaveChangesAsync() == 1);

            }
            catch (Exception e)
            {
                return false;
            }
        }
        public async Task<bool> DELETE(ICollection<T> entities)
        {
            try
            {
                _context.Set<T>().RemoveRange(entities);
                return (await _context.SaveChangesAsync() == entities.Count());

            }
            catch (Exception e)
            {
                return false;
            }
        }
        public IQueryable<T> Get()
        {
            //No track
            return _query.AsNoTracking().AsQueryable();
        }
    }
}
