using System;
using NodeCanvas.Framework;
using NUnit.Framework.Constraints;
using ParadoxNotion.Design;
using ParadoxNotion.Serialization.FullSerializer;
using Sirenix.OdinInspector;
using UnityEngine;

namespace NodeCanvas.Tasks.Conditions {

	[Category("Reset/Input")]
	[Description("Returns a float from two Vector3s")]
	public class GetMovementInputDotProduct : ConditionTask<PlayerControls>{
		enum CheckDotProductAgainst{
			ForwardDirection,
			CameraDirection,
			InputVector3
		}

		[ExposeField, fsSerializeAs] CheckDotProductAgainst checkAgainst;
		[ParadoxNotion.Design.ShowIf("checkAgainst", 2)] public BBParameter<Vector3> checkAgainstValue;
		[SliderField(-1f, 1f)] public BBParameter<float> desiredValue;
		public BBParameter<float> tolerance;

		public BBParameter<bool> considerCameraRotation;
		public BBParameter<bool> negate;

		//Use for initialization. This is called only once in the lifetime of the task.
		//Return null if init was successfull. Return an error string otherwise
		protected override string OnInit(){
			return null;
		}

		//This is called once each time the task is enabled.
		//Call EndAction() to mark the action as finished, either in success or failure.
		//EndAction can be called from anywhere.
		protected override bool OnCheck(){
			// Switch what the dot product is checked against
			Vector3 valueToCheck;

			switch (checkAgainst) {
				case CheckDotProductAgainst.ForwardDirection:
					Debug.Log(agent.transform.forward);
					valueToCheck = agent.transform.forward;
					break;
				case CheckDotProductAgainst.CameraDirection:
					valueToCheck = Camera.main.transform.forward;
					break;
				case CheckDotProductAgainst.InputVector3:
					valueToCheck = checkAgainstValue.value.normalized;
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
			
			// Get the input as a Vector3
			Vector3 rawInputVector3 = new Vector3(agent.rawMoveInput.x, 0f, agent.rawMoveInput.y);
			if (considerCameraRotation.value) {
				rawInputVector3 = Camera.main.transform.rotation * rawInputVector3;
			}
			
			// Calculate dor product
			float dotProduct = Vector3.Dot(valueToCheck, rawInputVector3);
			
			// Debug.Log(dotProduct);
			
			// Compare against the desired tolerance and output result
			if (tolerance.value > Mathf.Abs(dotProduct - tolerance.value)) {
				return true;
			}

			return false;
		}
		
		//Called when the task is disabled.
		protected override void OnEnable() {
			
		}

		//Called when the task is paused.
		protected override void OnDisable() {
			
		}
	}
}