using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.ViewModels;
using ComputerStoreDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.ConstrainedExecution;

namespace ComputerStoreDatabaseImplement.Models
{
    public class Consignment : IConsignmentModel
    {
        public int ID { get; private set; }

        [Required]
        public int OrderID { get; private set; }
        public virtual Order Order { get; set; }

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

        private Dictionary<int, (IProductModel, int)>? _consignmentProducts = null;

        [NotMapped]
        public Dictionary<int, (IProductModel, int)> ConsignmentProducts
        {
            get
            {
                if (_consignmentProducts == null)
                {
                    _consignmentProducts = Products.ToDictionary(recPC => recPC.ProductID, recPC => (recPC.Product as IProductModel, recPC.Count));
                }
                return _consignmentProducts;
            }
        }

        [ForeignKey("ConsignmentID")]
        public virtual List<ConsignmentProduct> Products { get; set; } = new();

        public static Consignment? Create(ComputerStoreDatabase context, ConsignmentBindingModel model)
        {
            if (model == null)
            {
                return null;
            }
            var products = context.Products;
            return new Consignment()
            {
                ID = model.ID,
                OrderID = model.OrderID,
                Price = model.Price,
                Products = model.ConsignmentProducts.Select(x => new ConsignmentProduct
                {
                    Product = context.Products.First(y => y.ID == x.Key),
                    Count = x.Value.Item2
                }).ToList()
            };
        }

        public void Update(ConsignmentBindingModel model)
        {
            if (model == null)
            {
                return;
            }
            Price = model.Price;
        }
        public ConsignmentViewModel GetViewModel => new()
        {
            ID = ID,
            OrderID = OrderID,
            Price = Price,
            ConsignmentProducts = ConsignmentProducts
        };

        public void UpdateProducts(ComputerStoreDatabase context, ConsignmentBindingModel model)
        {
            var consignmentProducts = context.ConsignmentProducts.Where(rec => rec.ConsignmentID == model.ID).ToList();
            if (consignmentProducts != null && consignmentProducts.Count > 0)
            {
                context.ConsignmentProducts.RemoveRange(consignmentProducts.Where(rec => !model.ConsignmentProducts.ContainsKey(rec.ProductID)));
                context.SaveChanges();
                foreach (var updateProduct in consignmentProducts)
                {
                    updateProduct.Count = model.ConsignmentProducts[updateProduct.ID].Item2;
                    model.ConsignmentProducts.Remove(updateProduct.ID);
                }
                context.SaveChanges();
            }

            var consignment = context.Consignments.First(x => x.ID == ID);
            foreach (var pc in model.ConsignmentProducts)
            {
                context.ConsignmentProducts.Add(new ConsignmentProduct
                {
                    Consignment = consignment,
                    Product = context.Products.First(x => x.ID == pc.Key),
                    Count = pc.Value.Item2
                });
                context.SaveChanges();
            }
            _consignmentProducts = null;
        }
    }
}