using CanteenContracts.BindingModels;
using CanteenContracts.View;
using CanteenDataModels.Models;
using FluentNHibernate.Conventions.Inspections;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace CanteenDatabaseImplement.Models
{
    //public class Product : IProductModel
    //{
    //    public int Id { get; private set; }
    //    [Required]
    //    public string ProductName { get; private set; } = string.Empty;
    //    [Required]
    //    public double Cost { get; private set; }
    //    [Required]
    //    public int ManagerId { get; private set; }
    //    private Dictionary<int, ICookModel>? _productCooks = null;
    //    [NotMapped]
    //    public Dictionary<int, ICookModel> ProductCooks
    //    {
    //        get
    //        {
    //            if (_productCooks == null)
    //            {
    //                _productCooks = Cooks.ToDictionary(record => record.CookId, record => record.Cook as ICookModel);
    //            }
    //            return _productCooks;
    //        }
    //    }
    //    [ForeignKey("ProductId")]
    //    public virtual List<ProductCook> Cooks { get; set; } = new();
    //    [ForeignKey("ProductId")]
    //    public virtual List<DishProduct> Dishes { get; set; } = new();
    //    public static Product? Create(CanteenDatabase context, ProductBindingModel model)
    //    {
    //        return new Product()
    //        {
    //            Id = model.Id,
    //            ProductName = model.ProductName,
    //            Cost = model.Cost,
    //            Cooks = model.ProductCooks.Select(x => new ProductCook
    //            {
    //                Cook = context.Cooks.First(y => y.Id == x.Key)
    //            }).ToList()
    //        };
    //    }

    //    public void Update(ProductBindingModel model)
    //    {
    //        ProductName = model.ProductName;
    //        Cost = model.Cost;
    //    }

    //    public ProductViewModel GetViewModel => new()
    //    {
    //        Id = Id,
    //        ProductName = ProductName,
    //        Cost = Cost,
    //        ProductCooks = ProductCooks,
    //        ManagerId = ManagerId
    //    };

    //    public void UpdateCooks(CanteenDatabase context, ProductBindingModel model)
    //    {
    //        var productCooks = context.ProductCooks.Where(record => record.ProductId == model.Id).ToList();
    //        if (productCooks != null && productCooks.Count > 0)
    //        {
    //            context.ProductCooks.RemoveRange(productCooks.Where(record => !model.ProductCooks.ContainsKey(record.CookId)));
    //            context.SaveChanges();
    //        }

    //        var product = context.Products.First(x => x.Id == Id);
    //        foreach (var pc in model.ProductCooks)
    //        {
    //            context.ProductCooks.Add(new ProductCook
    //            {
    //                Product = product,
    //                Cook = context.Cooks.First(x => x.Id == pc.Key),
    //            });
    //            context.SaveChanges();
    //        }

    //        _productCooks = null;
    //    }
    //}
    public class Product : IProductModel
    {
        public int Id { get; set; }

        [Required]
        public string ProductName { get; set; } = string.Empty;

        [Required]
        public double Price { get; set; }

        [Required]
        public int ManagerId { get; set; }

        private Dictionary<int, ICookModel>? _productCooks = null;

        [NotMapped]
        public Dictionary<int, ICookModel> ProductCooks
        {
            get
            {
                if (_productCooks == null)
                {
                    _productCooks = Cooks
                        .ToDictionary(recPC => recPC.CookId, recPC => (recPC.Cook as ICookModel));
                }
                return _productCooks;
            }
        }

        [ForeignKey("ProductId")]
        public virtual List<ProductCook> Cooks { get; set; } = new();
        [ForeignKey("ProductId")]
        public virtual List<LunchProduct> Lunches { get; set; } = new();
        [ForeignKey("ProductId")]
        public virtual List<DishProduct> Dishes { get; set; } = new();
        public virtual Manager Manager { get; set; }

        public static Product Create(CanteenDatabase context, ProductBindingModel model)
        {
            return new Product
            {
                Id = model.Id,
                ProductName = model.ProductName,
                Price = model.Price,
                ManagerId = model.ManagerId,
                Cooks = model.ProductCooks.Select(x => new ProductCook
                {
                    Cook = context.Cooks.First(y => y.Id == x.Key),
                }).ToList()
            };
        }

        public void Update(ProductBindingModel model)
        {
            ProductName = model.ProductName;
            Price = model.Price;
            ManagerId = model.ManagerId;
        }

        public ProductViewModel GetViewModel => new()
        {
            Id = Id,
            ProductName = ProductName,
            Price = Price,
            ManagerId = ManagerId,
            ProductCooks = ProductCooks
        };

        public void UpdateProductCooks(CanteenDatabase context, ProductBindingModel model)
        {
            var productCookers = context.ProductCook.Where(rec => rec.ProductId == model.Id).ToList();
            if (productCookers != null && (productCookers.Count() > 0))
            {
                context.ProductCook.RemoveRange(productCookers.Where(rec => !model.ProductCooks.ContainsKey(rec.CookId)));
                context.SaveChanges();
            }
            foreach (var updateCook in productCookers)
            {
                model.ProductCooks.Remove(updateCook.CookId);
            }
            context.SaveChanges();

            var product = context.Products.First(x => x.Id == Id);

            foreach (var pc in model.ProductCooks)
            {
                context.ProductCook.Add(new ProductCook
                {
                    Product = product,
                    Cook = context.Cooks.First(x => x.Id == pc.Key)
                });
                context.SaveChanges();
            }
            _productCooks = null;
        }
    }
}
