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

namespace SushiBarDatabaseImplement.Implements;

public class ImplementerStorage : IImplementerStorage
{
    public List<ImplementerViewModel> GetFullList()
    {
        using var context = new SushiBarDatabase();
        return context.Implementers
            .Select(x => x.GetViewModel)
            .ToList();
    }

    public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel? model)
    {
        if (model.Id.HasValue)
        {
            var res = GetElement(model);
            return res != null ? new List<ImplementerViewModel> { res } : new List<ImplementerViewModel>();
        }

        if (model.ImplementerFio == null) return new List<ImplementerViewModel>();
        using var context = new SushiBarDatabase();
        return context.Implementers
            .Where(x => x.ImplementerFio.Equals(model.ImplementerFio))
            .Select(x => x.GetViewModel)
            .ToList();
    }

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

    public ImplementerViewModel? Insert(ImplementerBindingModel model)
    {
        using var context = new SushiBarDatabase();
        var res = Implementer.Create(model);
        if (res == null) return res?.GetViewModel;
        context.Implementers.Add(res);
        context.SaveChanges();
        return res?.GetViewModel;
    }

    public ImplementerViewModel? Update(ImplementerBindingModel model)
    {
        using var context = new SushiBarDatabase();
        var res = context.Implementers
            .FirstOrDefault(x => x.Id == model.Id);
        if (res == null) return res?.GetViewModel;
        res.Update(model);
        context.SaveChanges();
        return res?.GetViewModel;
    }

    public ImplementerViewModel? Delete(ImplementerBindingModel model)
    {
        using var context = new SushiBarDatabase();
        var res = context.Implementers.FirstOrDefault(x => x.Id == model.Id);
        if (res == null) return res?.GetViewModel;
        context.Implementers.Remove(res);
        context.SaveChanges();
        return res?.GetViewModel;
    }
}