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

namespace BarListImplement.Implements
{
    public class OrderStorage : IOrderStorage
    {
        private readonly DataListSingleton _source;

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

        public List<OrderViewModel> GetFullList()
        {
            var Result = new List<OrderViewModel>();

            foreach (var Order in _source.Orders)
            {
                Result.Add(JoinCocktailName(Order.GetViewModel));
            }

            return Result;
        }

        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 => JoinClientFIO(JoinCocktailName(x.GetViewModel)))
                    .ToList();
            }

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

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

            foreach (var Order in _source.Orders)
            {
                if (Order.Id == Model.Id)
                {
                    return JoinCocktailName(Order.GetViewModel);
                }
            }

            return null;
        }

        public OrderViewModel? Insert(OrderBindingModel Model)
        {
            Model.Id = 1;
            foreach (var Order in _source.Orders)
            {
                if (Model.Id <= Order.Id)
                {
                    Model.Id = Order.Id + 1;
                }
            }

            var NewOrder = Order.Create(Model);

            if (NewOrder == null)
                return null;

            _source.Orders.Add(NewOrder);
            return JoinCocktailName(NewOrder.GetViewModel);
        }

        public OrderViewModel? Update(OrderBindingModel Model)
        {
            foreach (var Order in _source.Orders)
            {
                if (Order.Id == Model.Id)
                {
                    Order.Update(Model);
                    return JoinCocktailName(Order.GetViewModel);
                }
            }

            return null;
        }

        public OrderViewModel? Delete(OrderBindingModel Model)
        {
            for (int i = 0; i < _source.Orders.Count; ++i)
            {
                if (_source.Orders[i].Id == Model.Id)
                {
                    var Element = _source.Orders[i];
                    _source.Orders.RemoveAt(i);

                    return JoinCocktailName(Element.GetViewModel);
                }
            }

            return null;
        }

        private OrderViewModel JoinCocktailName(OrderViewModel Model)
        {
            var SelectedCocktail = _source.Cocktails.Find(reinforced => reinforced.Id == Model.CocktailId);

            if (SelectedCocktail != null)
            {
                Model.CocktailName = SelectedCocktail.CocktailName;
            }
            return Model;
        }

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

            if (SelectedClient != null)
            {
                Model.ClientFIO = SelectedClient.ClientFIO;
            }
            return Model;
        }
    }
}
