using ComputersShopContracts.BindingModels;
using ComputersShopContracts.ViewModels;
using ComputersShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ComputersShopFileImplement.Models
{
	public class Computer : IComputerModel
	{
		public int Id { get; private set; }
		public string ComputerName { get; private set; } = string.Empty;
		public double Price { get; private set; }
		public Dictionary<int, int> Components { get; private set; } = new();
		private Dictionary<int, (IComponentModel, int)>? _ComputerComponents = null;
		public Dictionary<int, (IComponentModel, int)> ComputerComponents
		{
			get
			{
				if (_ComputerComponents == null)
				{
					var source = DataFileSingleton.GetInstance();
					_ComputerComponents = Components.ToDictionary(x => x.Key, y =>
					((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!,
					y.Value));
				}
				return _ComputerComponents;
			}
		}
		public static Computer? Create(ComputerBindingModel model)
		{
			if (model == null)
			{
				return null;
			}
			return new Computer()
			{
				Id = model.Id,
				ComputerName = model.ComputerName,
				Price = model.Price,
				Components = model.ComputerComponents.ToDictionary(x => x.Key, x
			   => x.Value.Item2)
			};
		}
		public static Computer? Create(XElement element)
		{
			if (element == null)
			{
				return null;
			}
			return new Computer()
			{
				Id = Convert.ToInt32(element.Attribute("Id")!.Value),
				ComputerName = element.Element("ComputerName")!.Value,
				Price = Convert.ToDouble(element.Element("Price")!.Value),
				Components =
		   element.Element("ComputerComponents")!.Elements("ComputerComponent")
			.ToDictionary(x =>
		   Convert.ToInt32(x.Element("Key")?.Value), x =>
		   Convert.ToInt32(x.Element("Value")?.Value))
			};
		}
		public void Update(ComputerBindingModel model)
		{
			if (model == null)
			{
				return;
			}
			ComputerName = model.ComputerName;
			Price = model.Price;
			Components = model.ComputerComponents.ToDictionary(x => x.Key, x =>
		   x.Value.Item2);
			_ComputerComponents = null;
		}
		public ComputerViewModel GetViewModel => new()
		{
			Id = Id,
			ComputerName = ComputerName,
			Price = Price,
			ComputerComponents = ComputerComponents
		};
		public XElement GetXElement => new("Computer",
			new XAttribute("Id", Id),
			new XElement("ComputerName", ComputerName),
			new XElement("Price", Price.ToString()),
			new XElement("ComputerComponents", Components.Select(x => new XElement("ComputerComponent", new XElement("Key", x.Key), new XElement("Value", x.Value)))

	   .ToArray()));

	}
}