using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.ViewModels;
using ComputerStoreDataModels.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace ComputerStoreDatabaseImplement.Models
{
    public class PC : IPCModel
    {
        public int ID { get; private set; }

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

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

        [Required]
        public int EmployeeID { get; private set; }

        [Required]
        public int RequestID { get; private set; }        

        [NotMapped]
        public Dictionary<int, (IComponentModel, int)> PCComponents { get; private set; } = new();
        
              
        public virtual Employee Employee { get; set; }

        public virtual Request Request { get; set; }

        public static PC Create(ComputerStoreDatabase context, PCBindingModel model)
        {           
            return new PC()
            {
                ID = model.ID,
                Name = model.Name,
                Price = model.Price,
                EmployeeID = model.EmployeeID,
                Employee = context.Employees.First(x => x.ID == model.EmployeeID),
                Request = context.Requests.First(x => x.ID == model.RequestID),
                RequestID = model.RequestID,
                PCComponents = model.PCComponents
            };
        }

        public static void EnterPCID(ComputerStoreDatabase context, PC model)
        {
            foreach(var rc in context.RequestComponents.Where(x => x.RequestID == model.RequestID))
            {
                rc.PCID = model.ID;
            }
           
            context.SaveChanges();
        }

        public void Update(PCBindingModel model)
        {
            Name = model.Name;
            Price = model.Price;
            PCComponents = model.PCComponents;
        }

        public PCViewModel GetViewModel 
        {
            
            get
            {
                using var context = new ComputerStoreDatabase();
                return new PCViewModel
                {
                    ID = ID,
                    Name = Name,
                    Price = Price,
                    EmployeeID = EmployeeID,
                    EmployeeUsername = Employee.Username,
                    RequestID = RequestID,
                    PCComponents = context.RequestComponents.Include(x => x.Component).Where(x => x.PCID == ID).ToDictionary(x => x.ComponentID, x => (x.Component as IComponentModel, x.Count))
                };
            }
            
        }

        public void UpdateComponents(ComputerStoreDatabase context, PCBindingModel model)
        {
            var pcComponents = context.RequestComponents.Where(rec => rec.PCID == model.ID && rec.RequestID == model.RequestID).ToList();
            if(pcComponents != null &&  pcComponents.Count > 0)
            {
                if(pcComponents.Where(rec => !model.PCComponents.ContainsKey(rec.ComponentID) && rec.RequestID == model.RequestID).Any())
                {
                    context.RequestComponents.RemoveRange(pcComponents.Where(rec => !model.PCComponents.ContainsKey(rec.ComponentID) && rec.RequestID == model.RequestID));
                    context.SaveChanges();
                }
               
                foreach(var updateComponent  in pcComponents.Where(x => model.PCComponents.ContainsKey(x.ComponentID) && x.RequestID == model.RequestID))
                {
                    updateComponent.Count = model.PCComponents[updateComponent.ComponentID].Item2;
                    model.PCComponents.Remove(updateComponent.ComponentID);
                }
                context.SaveChanges();
            }

            foreach(var pcc in model.PCComponents )
            {
                context.RequestComponents.Add(new RequestComponent
                {
                    Component = context.Components.First(x=> x.ID == pcc.Key),
                    Request = context.Requests.First(x => x.ID == model.RequestID),
                    Count = pcc.Value.Item2
                });
                context.SaveChanges();
            }
            
        }

    }
}