using Godot;
using System;
using System.Collections.Generic;

public partial class DebugStats : Node
{
	//public DebugStats Stats => GetNode<DebugStats>("VBoxContainer");

	private class Property
	{
		public string NumFormat { get; set; } = "%4.2f";
		public Node Object { get; set; } // The object being tracked.
		public string PropertyPath { get; set; } // The property to display (NodePath).
		public Label LabelRef { get; set; } // A reference to the Label.
		public string Display { get; set; } // Display option (rounded, etc.)

		public Property(Node obj, string property, Label label, string display)
		{
			Object = obj;
			PropertyPath = property;
			LabelRef = label;
			Display = display;
		}

		public void SetLabel()
		{
			// Sets the label's text.
			string s = $"{Object.Name}/{PropertyPath} : ";
			var p = Object.GetIndexed(PropertyPath);

			switch (Display)
			{
				case "":
					s += p.ToString();
					break;
				case "length":
					// Handle length for Vector2 and Vector3
					if (p.VariantType == Variant.Type.Vector2)
					{
						Vector2 v2 = p.As<Vector2>();
						s += string.Format(NumFormat, v2.Length());
					}
					else if (p.VariantType == Variant.Type.Vector3)
					{
						Vector3 v3 = p.As<Vector3>();
						s += string.Format(NumFormat, v3.Length());
					}
					else
					{
						s += "N/A"; // Handle non-applicable types
					}
					break;
				case "round":
					// For handling numbers (int and float)
					if (p.VariantType == Variant.Type.Float || p.VariantType == Variant.Type.Int)
					{
						s += string.Format(NumFormat, p.As<float>());
					}
					else if (p.VariantType == Variant.Type.Vector2)
					{
						Vector2 v2Round = p.As<Vector2>();
						s += v2Round.Round().ToString();
					}
					else if (p.VariantType == Variant.Type.Vector3)
					{
						Vector3 v3Round = p.As<Vector3>();
						s += v3Round.Round().ToString();
					}
					break;
			}

			LabelRef.Text = s;
		}
	}

	private List<Property> props = new List<Property>(); // An array of the tracked properties.


	public static DebugStats Instance { get; private set; }
	public override void _Ready()
	{
		Instance = this;
	}

	public override void _Process(double delta)
	{
		// if (!Visible)
		// 	return;

		foreach (var prop in props)
		{
			prop.SetLabel();
		}
	}

	public void AddProperty(Node obj, string property, string display)
	{
		Label label = new Label();
		label.Set("custom_fonts/font", GD.Load<Font>("res://fonts/Xolonium-Regular.ttf"));
		GetNode<VBoxContainer>("VBoxContainer").AddChild(label);

		props.Add(new Property(obj, property, label, display));
	}

	public void RemoveProperty(Node obj, string property)
	{
		props.RemoveAll(prop => prop.Object == obj && prop.PropertyPath == property);
	}
}
