using UnityEngine;
using RenownedGames.AITree;

namespace AC.Downloads.AITree
{

	public class BlackboardLink : MonoBehaviour
	{

		[SerializeField] private BehaviourRunner behaviourRunner = null;
		private Blackboard blackboard;


		private void OnValidate ()
		{
			if (behaviourRunner == null) behaviourRunner = GetComponent<BehaviourRunner> ();
		}


		private void OnEnable ()
		{
			EventManager.OnDownloadVariable += OnDownload;
			EventManager.OnUploadVariable += OnUpload;
		}


		private void OnDisable ()
		{
			EventManager.OnDownloadVariable -= OnDownload;
			EventManager.OnUploadVariable -= OnUpload;
		}


		private void OnDownload (GVar variable, Variables variables)
		{
			if (Blackboard == null) return;

			foreach (Key key in blackboard.Keys)
			{
				if (key.name == variable.label && LocationIsCorrect (variable))
				{
					switch (variable.type)
					{
						case VariableType.Boolean:
							if (key is BoolKey boolKey)
							{
								variable.BooleanValue = boolKey.GetValue ();
							}
							break;

						case VariableType.Integer:
							if (key is IntKey intKey)
							{
								variable.IntegerValue = intKey.GetValue ();
							}
							break;

						case VariableType.Float:
							if (key is FloatKey floatKey)
							{
								variable.FloatValue = floatKey.GetValue ();
							}
							break;

						case VariableType.String:
							if (key is StringKey stringKey)
							{
								variable.TextValue = stringKey.GetValue ();
							}
							break;

						case VariableType.Vector3:
							if (key is Vector3Key vector3Key)
							{
								variable.Vector3Value = vector3Key.GetValue ();
							}
							break;

						case VariableType.GameObject:
							if (key is TransformKey transformKey)
							{
								Transform _transform = transformKey.GetValue ();
								variable.GameObjectValue = _transform ? _transform.gameObject : null;
							}
							break;


						default:
							break;
					}
					return;
				}
			}
		}


		private void OnUpload (GVar variable, Variables variables)
		{
			if (Blackboard == null) return;

			foreach (Key key in blackboard.Keys)
			{
				if (key.name == variable.label && LocationIsCorrect (variable))
				{
					switch (variable.type)
					{
						case VariableType.Boolean:
							if (key is BoolKey boolKey)
							{
								boolKey.SetValue (variable.BooleanValue);
							}
							break;

						case VariableType.Integer:
							if (key is IntKey intKey)
							{
								intKey.SetValue (variable.IntegerValue);
							}
							break;

						case VariableType.Float:
							if (key is FloatKey floatKey)
							{
								floatKey.SetValue (variable.FloatValue);
							}
							break;

						case VariableType.String:
							if (key is StringKey stringKey)
							{
								stringKey.SetValue (variable.TextValue);
							}
							break;

						case VariableType.Vector3:
							if (key is Vector3Key vector3Key)
							{
								vector3Key.SetValue (variable.Vector3Value);
							}
							break;

						case VariableType.GameObject:
							if (key is TransformKey transformKey)
							{
								GameObject _gameObject = variable.GameObjectValue;
								transformKey.SetValue (_gameObject ? _gameObject.transform : null);
							}
							break;

						default:
							break;
					}
					return;
				}
			}
		}


		private bool LocationIsCorrect (GVar variable)
		{
			Variables variables = GetComponent<Variables> ();
			if (variables)
			{
				return variables.vars.Contains (variable);
			}

			return KickStarter.runtimeVariables.globalVars.Contains (variable);
		}



		private Blackboard Blackboard
		{
			get
			{
				if (blackboard == null)
				{
					BehaviourRunner behaviourRunner = GetComponent<BehaviourRunner> ();
					blackboard = behaviourRunner.GetBlackboard ();
				}
				return blackboard;
			}
		}


	}

}