using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using SushiBarFileImplement.Models;

namespace SushiBarFileImplement.Implements
{
    public class SushiStorage : ISushiStorage
    {
        private readonly DataFileSingleton source;

        public SushiStorage()
        {
            source = DataFileSingleton.GetInstance();
        }
        public SushiViewModel? Delete(SushiBindingModel model)
        {
            var element = source.Sushis.FirstOrDefault(x => x.Id == model.Id);
            if (element != null)
            {
                source.Sushis.Remove(element);
                source.SaveSushis();
                return element.GetViewModel;
            }
            return null;
        }

        public SushiViewModel? GetElement(SushiSearchModel model)
        {
            if (string.IsNullOrEmpty(model.SushiName) && !model.Id.HasValue)
            {
                return null;
            }
            return source
                .Sushis
                .FirstOrDefault(x =>
                    (!string.IsNullOrEmpty(model.SushiName) 
                    && x.SushiName == model.SushiName) 
                    || (model.Id.HasValue && x.Id == model.Id))
                ?.GetViewModel;
        }

        public List<SushiViewModel> GetFilteredList(SushiSearchModel model)
        {
            if (string.IsNullOrEmpty(model.SushiName))
            {
                return new();
            }
            return source.Sushis
                .Where(x => x.SushiName.Contains(model.SushiName))
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public List<SushiViewModel> GetFullList()
        {
            return source
                .Sushis
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public SushiViewModel? Insert(SushiBindingModel model)
        {
            model.Id = source.Sushis.Count > 0 ? source.Sushis.Max(x => x.Id) + 1 : 1;
            var newSushi = Sushi.Create(model);
            if (newSushi == null)
            {
                return null;
            }
            source.Sushis.Add(newSushi);
            source.SaveSushis();
            return newSushi.GetViewModel;
        }

        public SushiViewModel? Update(SushiBindingModel model)
        {
            var sushi = source.Sushis.FirstOrDefault(x => x.Id == model.Id);
            if (sushi == null)
            {
                return null;
            }
            sushi.Update(model);
            source.SaveSushis();
            return sushi.GetViewModel;
        }
    }
}
