using Contracts.BindingModels;
using Contracts.ViewModels;
using DataModels.Enums;
using DataModels.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseImplement.Models
{
    public class Supply : ISupply
    {
        public Guid Id { get; set; }
        [Required]
        public string Name { get; set; } = string.Empty;
        [Required]
        public double Price { get; set; }
        [Required]
        public Guid SupplierId { get; set; }
        [Required]
        public DateTime Date { get; set; }
        [Required]
        public SupplyStatus Status { get; set; } = SupplyStatus.Pending;
        private Dictionary<Guid, (IProduct, int)>? _supplyProducts = null;
        [NotMapped]
        public Dictionary<Guid, (IProduct, int)> SupplyProducts
        {
            get
            {
                if (_supplyProducts == null)
                {
                    _supplyProducts = Products
                    .ToDictionary(recPC => recPC.Id, recPC =>
                    (recPC.Product as IProduct, recPC.Count));
                }
                return _supplyProducts;
            }
        }
        [ForeignKey("SupplyId")]
        public virtual List<SupplyProduct> Products { get; set; } = new();
        public virtual Supplier Supplier { get; set; }
        public static Supply Create(Database context, SupplyBindingModel model)
        {
            return new Supply()
            {
                Id = model.Id,
                Name = model.Name,
                Price = model.Price,
                Date = model.Date,
                SupplierId = model.SupplierId,
                Products = model.SupplyProducts.Select(x => new
                SupplyProduct
                {
                    Product = context.Products.First(y => y.Id == x.Key),
                    Count = x.Value.Item2
                }).ToList()
            };
        }
        public void Update(SupplyBindingModel model)
        {
            Name = model.Name;
            Price = model.Price;
        }
        public SupplyViewModel GetViewModel
        {
            get
            {
                var context = new Database();
                return new()
                {
                    Id = Id,
                    Name = Name,
                    Price = Price,
                    Products = SupplyProducts,
                    Date = Date,
                    Status = Status,
                    SupplierName = context.Suppliers.FirstOrDefault(x => x.Id == Id)?.Name ?? string.Empty,
                };
            }
        }
        public void UpdateProducts(Database context, SupplyBindingModel model)
        {
            var supplyProducts = context.SupplyProducts.Where(rec =>
            rec.Id == model.Id).ToList();
            if (supplyProducts != null && supplyProducts.Count > 0)
            { // удалили те, которых нет в модели
                context.SupplyProducts.RemoveRange(supplyProducts.Where(rec
                => !model.SupplyProducts.ContainsKey(rec.ProductId)));
                context.SaveChanges();
                // обновили количество у существующих записей
                foreach (var updateProduct in supplyProducts)
                {
                    updateProduct.Count = model.SupplyProducts[updateProduct.ProductId].Item2;
                    model.SupplyProducts.Remove(updateProduct.ProductId);
                }
                context.SaveChanges();
            }
            var supply = context.Supplies.First(x => x.Id == Id);
            foreach (var pc in model.SupplyProducts)
            {
                context.SupplyProducts.Add(new SupplyProduct
                {
                    Supply = supply,
                    Product = context.Products.First(x => x.Id == pc.Key),
                    Count = pc.Value.Item2
                });
                context.SaveChanges();
            }
            _supplyProducts = null;
        }
    }
}