using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using BarDatabaseImplement.Models;

namespace BarDatabaseImplement.Implements
{
    public class ClientStorage : IClientStorage
    {
        public List<ClientViewModel> GetFullList()
        {
            using var Context = new BarDatabase();
            
            return Context.Clients
                .Select(x => x.GetViewModel)
                .ToList();
        }
        
        public List<ClientViewModel> GetFilteredList(ClientSearchModel Model)
        {
            if (string.IsNullOrEmpty(Model.ClientFIO) && string.IsNullOrEmpty(Model.Email))
                return new();

            using var Context = new BarDatabase();
            
            return Context.Clients
                .Where(x => 
                    (!string.IsNullOrEmpty(Model.ClientFIO) && x.ClientFIO.Contains(Model.ClientFIO)) ||
                    (!string.IsNullOrEmpty(Model.Email) && x.Email.Contains(Model.Email)))
                .Select(x => x.GetViewModel)
                .ToList();
        }
        
        public ClientViewModel? GetElement(ClientSearchModel Model)
        {
            if (string.IsNullOrEmpty(Model.ClientFIO) && string.IsNullOrEmpty(Model.Email) && string.IsNullOrEmpty(Model.Password) &&
               !Model.Id.HasValue)
            {
                return null;
            }
            
            using var Context = new BarDatabase();
            
            return Context.Clients
                .FirstOrDefault(x => (string.IsNullOrEmpty(Model.ClientFIO) || x.ClientFIO == Model.ClientFIO) &&
                    (!Model.Id.HasValue || x.Id == Model.Id) && (string.IsNullOrEmpty(Model.Email) || x.Email == Model.Email) &&
                    (string.IsNullOrEmpty(Model.Password) || x.Password == Model.Password))?
                .GetViewModel;
        }
        
        public ClientViewModel? Insert(ClientBindingModel Model)
        {
            var NewClient = Client.Create(Model);
            if (NewClient == null)
                return null;

            using var Context = new BarDatabase();
            
            Context.Clients.Add(NewClient);
            Context.SaveChanges();
            
            return NewClient.GetViewModel;
        }
        
        public ClientViewModel? Update(ClientBindingModel Model)
        {
            using var Context = new BarDatabase();
            var Client = Context.Clients.FirstOrDefault(x => x.Id == Model.Id);
            
            if (Client == null)
                return null;

            Client.Update(Model);
            Context.SaveChanges();
            
            return Client.GetViewModel;
        }
        
        public ClientViewModel? Delete(ClientBindingModel Model)
        {
            using var Context = new BarDatabase();
            var Element = Context.Clients.FirstOrDefault(rec => rec.Id == Model.Id);

            if (Element == null)
                return null;

            Context.Clients.Remove(Element);
            Context.SaveChanges();
            
            return Element.GetViewModel;
        }
    }
}
