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

namespace SushiBarFileImplement.Implements;

public class ImplementerStorage : IImplementerStorage
{
    private readonly DataFileSingleton _source;
    public ImplementerStorage()
    {
        _source = DataFileSingleton.GetInstance();
    }
    
    public List<ImplementerViewModel> GetFullList()
    {
        return _source.Implementers.Select(x => x.GetViewModel).ToList();
    }

    public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel? model)
    {
        if (model == null)
        {
            return new List<ImplementerViewModel>();
        }
        if (model.Id.HasValue)
        {
            var res = GetElement(model);
            return res != null ? 
                new List<ImplementerViewModel> { res } : 
                new List<ImplementerViewModel>();
        }
        if (model.ImplementerFio != null)
        {
            return _source.Implementers
                .Where(x => x.ImplementerFio.Equals(model.ImplementerFio))
                .Select(x => x.GetViewModel)
                .ToList();
        }
        return new List<ImplementerViewModel>();
    }

    public ImplementerViewModel? GetElement(ImplementerSearchModel? model)
    {
        if (model.Id.HasValue)
            return _source.Implementers.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
        if (model is { ImplementerFio: { }, Password: { } })
            return _source.Implementers
                .FirstOrDefault(x => x.ImplementerFio.Equals(model.ImplementerFio)
                                     && x.Password.Equals(model.Password))
                ?.GetViewModel;
        return model.ImplementerFio != null ?
            _source.Implementers
                .FirstOrDefault(x => x.ImplementerFio.Equals(model.ImplementerFio))?.GetViewModel : 
            null;
    }

    public ImplementerViewModel? Insert(ImplementerBindingModel model)
    {
        model.Id = _source.Implementers.Count > 0 ?
            _source.Implementers.Max(x => x.Id) + 1 : 
            1;
        var res = Implementer.Create(model);
        if (res == null) return res?.GetViewModel;
        _source.Implementers.Add(res);
        _source.SaveImplementers();
        return res?.GetViewModel;
    }

    public ImplementerViewModel? Update(ImplementerBindingModel model)
    {
        var res = _source.Implementers.FirstOrDefault(x => x.Id == model.Id);
        if (res == null) return res?.GetViewModel;
        res.Update(model);
        _source.SaveImplementers();
        return res?.GetViewModel;
    }

    public ImplementerViewModel? Delete(ImplementerBindingModel model)
    {
        var res = _source.Implementers.FirstOrDefault(x => x.Id == model.Id);
        if (res == null) return res?.GetViewModel;
        _source.Implementers.Remove(res);
        _source.SaveImplementers();
        return res?.GetViewModel;
    }
}