using ElectronicsShopContracts.BindingModels;
using ElectronicsShopContracts.ViewModels;
using ElectronicsShopDataModels.Enums;
using ElectronicsShopDataModels.Models;
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElectronicsShopDataBaseImplement.Models
{
    public class Order : IOrderModel
    {
        public int ID { get; set; }

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

        [ForeignKey("ClientID")]
        public int ClientID { get; set; }

        [Required]
        public DateTime DateCreate {  get; set; } = DateTime.Now;

        [Required]
		public OrderStatus Status { get; set; } = OrderStatus.Неоплачено;

		public Dictionary<int, (IProductModel, int)>? _productList = null;

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

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

		public static Order? Create(Database context ,OrderBindingModel? model)
        {
            if (model == null)
            {
                return null;
            }
            return new Order()
            {
                ID = model.ID,
                ClientID=model.ClientID,
                Sum = model.Sum,
                DateCreate = model.DateCreate,
                Products = model.ProductList.Select(x => new OrderProduct
                {
                    _product = context.Products.First(y => y.ID == x.Key),
                    Count = x.Value.Item2
                }).ToList(),
                Status = model.Status,
            };
        }

        public OrderViewModel GetViewModel => new()
        {
            ID = ID,
            ClientID = ClientID,
            Sum = Sum,
            DateCreate = DateCreate,
            ProductList = ProductList,
            Status = Status,
        };

		public void Update(OrderBindingModel model) {
            if (model == null) {
                return;
            }
            Sum = model.Sum;
            Status = model.Status;
        }

        public void UpdateProducts(Database context,OrderBindingModel model) {
            var orderProducts = context.OrderProducts.Where(rec => rec.OrderID == model.ID).ToList();
            if (orderProducts != null && orderProducts.Count > 0) {
                // нужно удалить те, которые отсутствуют в модели
                context.OrderProducts.RemoveRange(orderProducts.Where(rec => !model.ProductList.ContainsKey(rec.ProductID)));
                context.SaveChanges();

                foreach (var updateProducts in orderProducts) {
                    updateProducts.Count = model.ProductList[updateProducts.ProductID].Item2;
                    model.ProductList.Remove(updateProducts.ProductID);
                }
                context.SaveChanges();
            }
            var order = context.Orders.FirstOrDefault(x => x.ID == model.ID);

            if (order == null) {

                throw new Exception("Ошибка получения заказа");
            }

            order.Sum = model.Sum;
            foreach (var op in model.ProductList) {
                context.OrderProducts.Add(new OrderProduct {
                    _order = order,
                    _product = context.Products.First(x => x.ID == op.Key),
                    Count = op.Value.Item2,
                });
                context.SaveChanges();
            }
            _productList = null;
        }

        public void DeleteProducts(Database context, OrderBindingModel model) {
			var orderProducts = context.OrderProducts.Where(rec => rec.OrderID == model.ID).ToList();
			context.OrderProducts.RemoveRange(orderProducts.Where(rec => !model.ProductList.ContainsKey(rec.ProductID)));
            context.SaveChanges();
		}
	}
}