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

namespace BarFileImplement.Implements
{
    public class OrderStorage : IOrderStorage
    {
        private readonly DataFileSingleton _source;

        public OrderStorage()
        {
            _source = DataFileSingleton.GetInstance();
        }

        public List<OrderViewModel> GetFullList()
        {
            return _source.Orders.Select(x => AddCocktailName(x.GetViewModel)).ToList();
        }

        public List<OrderViewModel> GetFilteredList(OrderSearchModel Model)
        {
            if (Model.DateFrom.HasValue)
            {
                return _source.Orders
                    .Where(x => (x.DateCreate >= Model.DateFrom && x.DateCreate <= Model.DateTo) && (!Model.ClientId.HasValue || x.ClientId == Model.ClientId))
                    .Select(x => AddClientFIO(AddCocktailName(x.GetViewModel)))
                    .ToList();
            }

            return _source.Orders
                .Where(x => (Model.Id.HasValue && x.Id == Model.Id) || (Model.ClientId.HasValue && x.ClientId == Model.ClientId))
                .Select(x => AddClientFIO(AddCocktailName(x.GetViewModel)))
                .ToList();
        }

        public OrderViewModel? Delete(OrderBindingModel Model)
        {
            var Element = _source.Orders.FirstOrDefault(x => x.Id == Model.Id);

            if (Element != null)
            {
                _source.Orders.Remove(Element);
                _source.SaveOrders();

                return AddCocktailName(Element.GetViewModel);
            }

            return null;
        }

        public OrderViewModel? GetElement(OrderSearchModel Model)
        {
            if (!Model.Id.HasValue)
                return null;

            var Order = _source.Orders.FirstOrDefault(x => (Model.Id.HasValue && x.Id == Model.Id));

            if (Order == null)
                return null;

            return AddCocktailName(Order.GetViewModel);
        }

        public OrderViewModel? Insert(OrderBindingModel Model)
        {
            Model.Id = _source.Orders.Count > 0 ? _source.Orders.Max(x => x.Id) + 1 : 1;

            var NewOrder = Order.Create(Model);

            if (NewOrder == null)
                return null;

            _source.Orders.Add(NewOrder);
            _source.SaveOrders();

            return AddCocktailName(NewOrder.GetViewModel);
        }

        public OrderViewModel? Update(OrderBindingModel Model)
        {
            var Order = _source.Orders.FirstOrDefault(x => x.Id == Model.Id);

            if (Order == null)
                return null;

            Order.Update(Model);
            _source.SaveOrders();

            return AddCocktailName(Order.GetViewModel);
        }

        private OrderViewModel AddCocktailName(OrderViewModel Model)
        {
            var SelectedCocktail = _source.Cocktails.FirstOrDefault(x => x.Id == Model.CocktailId);

            Model.CocktailName = SelectedCocktail?.CocktailName ?? string.Empty;
            return Model;
        }

        public OrderViewModel AddClientFIO(OrderViewModel Model)
        {
            var SelectedClient = _source.Clients.FirstOrDefault(x => x.Id == Model.Id);

            Model.ClientFIO = SelectedClient?.ClientFIO ?? string.Empty;
            return Model;
        }
    }
}
