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

namespace BarFileImplement.Implements
{
    public class ClientStorage : IClientStorage
    {
        private readonly DataFileSingleton _source;
        public ClientStorage()
        {
            _source = DataFileSingleton.GetInstance();
        }
        
        public List<ClientViewModel> GetFullList()
        {
            return _source.Clients
                .Select(x => x.GetViewModel)
                .ToList();
        }
        
        public List<ClientViewModel> GetFilteredList(ClientSearchModel Model)
        {
            if (string.IsNullOrEmpty(Model.ClientFIO) && string.IsNullOrEmpty(Model.Email))
                return new();

            return _source.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)
        {
            return _source.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)
        {
            Model.Id = _source.Clients.Count > 0 ? _source.Clients.Max(x => x.Id) + 1 : 1;
            
            var NewClient = Client.Create(Model);
            if (NewClient == null)
                return null;

            _source.Clients.Add(NewClient);
            _source.SaveClients();
            
            return NewClient.GetViewModel;
        }
        
        public ClientViewModel? Update(ClientBindingModel Model)
        {
            var Client = _source.Clients.FirstOrDefault(x => x.Id == Model.Id);
            if (Client == null)
                return null;

            Client.Update(Model);
            _source.SaveClients();
           
            return Client.GetViewModel;
        }
        
        public ClientViewModel? Delete(ClientBindingModel Model)
        {
            var Client = _source.Clients.FirstOrDefault(rec => rec.Id == Model.Id);
            if (Client == null)
                return null;

            _source.Clients.Remove(Client);
            _source.SaveClients();
            
            return Client.GetViewModel;
        }
    }
}
