using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace UP_Session1_Belov.Models
{
    internal class ProductListModel : INotifyPropertyChanged
    {
        List<ProductModel> products = new List<ProductModel>();

        private List<FilterModel> filters = new List<FilterModel>();

        private int idFilterModel;

        private int allCount;

        private string search = string.Empty;

        private List<SortModel> sortCbName = new List<SortModel>();

        private int idSortModel;

        public ProductListModel()
        {
            using(UP_41P_BelovRAEntities db = new UP_41P_BelovRAEntities())
            {
                List<Product> productsFromBase = db.Product.Include(x => x.Manufacturer).ToList();
                foreach(var product in productsFromBase)
                {
                    products.Add(new ProductModel(product.ProductArticleNumber,
                                                  product.ProductName,
                                                  product.ProductDescription,
                                                  product.Manufacturer.ManufacturerName,
                                                  Convert.ToDouble(product.ProductCost),
                                                  Convert.ToDouble(product.ProductDiscountAmount),
                                                  product.ProductPhoto));
                }

                filters.Add(new FilterModel(0, 0, 0, "Все"));
                filters.Add(new FilterModel(1, 0, 9.99, "0-9.99%"));
                filters.Add(new FilterModel(2, 10, 14.99, "10-14.99%"));
                filters.Add(new FilterModel(3, 15, 100, "15% и более"));

                allCount = products.Count;

                sortCbName.Add(new SortModel(0, "По возрастанию"));
                sortCbName.Add(new SortModel(1, "По убыванию"));
                idSortModel = 0;

                idFilterModel = 0;
                Sort();
            }
        }

        public List<ProductModel> Products
        {
            get => products; set
            {
                products = value;
                OnPropertyChanged("Products");
            }
        }

        public void Sort()
        {
            List<ProductModel> baseList = new List<ProductModel>();
            using (UP_41P_BelovRAEntities db = new UP_41P_BelovRAEntities())
            {
                List<Product> productsBase = db.Product.ToList();

                foreach (var product in productsBase)
                {
                    baseList.Add(
                        new ProductModel(
                            product.ProductArticleNumber,
                            product.ProductName,
                            product.ProductDescription,
                            product.Manufacturer != null ? product.Manufacturer.ManufacturerName : "", // Handling possible null reference
                            Convert.ToDouble(product.ProductCost),
                            Convert.ToDouble(product.ProductDiscountAmount),
                            product.ProductPhoto
                        )
                    );
                }

                switch (IdFilterModel)
                {
                    case 0: break;
                    case 1:
                        baseList = baseList.Where(x => x.Discount >= filters[1].FirstRange && x.Discount <= filters[1].SecondRange).ToList();
                        break;
                    case 2:
                        baseList = baseList.Where(x => x.Discount >= filters[2].FirstRange && x.Discount <= filters[2].SecondRange).ToList();
                        break;
                    case 3:
                        baseList = baseList.Where(x => x.Discount >= filters[3].FirstRange && x.Discount <= filters[3].SecondRange).ToList();
                        break;
                    default:
                        break;
                }

                if (Search != string.Empty)
                {
                    baseList = baseList.Where(x => x.Name.ToLower().StartsWith(Search.ToLower())).ToList();
                }

                switch (IdSortModel)
                {
                    case 0:
                        baseList = baseList.OrderBy(x => x.CostWithDiscount).ToList(); // Corrected: added .ToList()
                        break;
                    case 1:
                        baseList = baseList.OrderByDescending(x => x.CostWithDiscount).ToList(); // Corrected: added .ToList()
                        break;
                    default:
                        break;
                }
            }
            Products = baseList;
        }

        public List<FilterModel> Filters { get => filters; set => filters = value; }
        public int IdFilterModel
        {
            get => idFilterModel;
            set
            {
                idFilterModel = value;
                OnPropertyChanged("IdFilterModel");
                Sort();
            }
        }

        public int AllCount
        {
            get => allCount;
            set
            {
                allCount = value;
                OnPropertyChanged("AllCount");
            }
        }

        public string Search
        {
            get => search;
            set
            {
                search = value;
                OnPropertyChanged("Search");
                Sort();
            }
        }

        public List<SortModel> SortCbName { get => sortCbName; set => sortCbName = value; }
        public int IdSortModel
        {
            get => idSortModel;
            set
            {
                idSortModel = value;
                OnPropertyChanged("IdSortModel");
                Sort();
            }
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
