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

namespace BarListImplement.Implements
{
    public class ClientStorage : IClientStorage
    {
        private readonly DataListSingleton _source;
        
        public ClientStorage()
        {
            _source = DataListSingleton.GetInstance();
        }
        
        public List<ClientViewModel> GetFullList()
        {
            var Result = new List<ClientViewModel>();
            
            foreach (var Client in _source.Clients)
            {
                Result.Add(Client.GetViewModel);
            }
            
            return Result;
        }
        
        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)
        {
            foreach (var Client in _source.Clients)
            {
                if ((string.IsNullOrEmpty(Model.ClientFIO) || Client.ClientFIO == Model.ClientFIO) &&
                    (!Model.Id.HasValue || Client.Id == Model.Id) && (string.IsNullOrEmpty(Model.Email) || Client.Email == Model.Email) &&
                    (string.IsNullOrEmpty(Model.Password) || Client.Password == Model.Password))
                {
                    return Client.GetViewModel;
                }
            }
            
            return null;
        }
        
        public ClientViewModel? Insert(ClientBindingModel Model)
        {
            Model.Id = 1;
            foreach (var Client in _source.Clients)
            {
                if (Model.Id <= Client.Id)
                {
                    Model.Id = Client.Id + 1;
                }
            }
            
            var NewClient = Client.Create(Model);
            if (NewClient == null)
                return null;

            _source.Clients.Add(NewClient);
            return NewClient.GetViewModel;
        }
        
        public ClientViewModel? Update(ClientBindingModel Model)
        {
            foreach (var Client in _source.Clients)
            {
                if (Client.Id == Model.Id)
                {
                    Client.Update(Model);
                    return Client.GetViewModel;
                }
            }
            
            return null;
        }
        public ClientViewModel? Delete(ClientBindingModel Model)
        {
            for (int i = 0; i < _source.Clients.Count; ++i)
            {
                if (_source.Clients[i].Id == Model.Id)
                {
                    var Element = _source.Clients[i];
                    _source.Clients.RemoveAt(i);
                    
                    return Element.GetViewModel;
                }
            }
            
            return null;
        }
    }
}
