using Godot;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

public partial class Worker : RigidBody2D
{
	public bool _dead = false, _hovered = false, _held = false, _placed = false, _selected = false, _primed = false, _moving = false;
	public int _health, _healthMax, _aptitude, _agility, _ardor, _accumen, _awareness, _appeal, _id;
	public float _rotationalForce = 0;
	public Vector2 _force = Vector2.Zero;
	public Node _collisionTarget;
	public Sprite2D _image;
	public ProgressBar _healthBar;
	public Manager _manager;
	public List<Action> _Actions = new();
	public override void _Ready()
	{
		_health = 10;
		_aptitude = 5;
		_agility = 5;
		_ardor = 5;
		_accumen = 5;
		_awareness = 5;
		_appeal = 5;

		_healthMax = _health;
		_image = GetNode<Sprite2D>("Sprite2D");

		_Actions.Add(new BasicAttack(this));

		_healthBar = GetNode<ProgressBar>("HealthBar");
		_healthBar.MaxValue = _healthMax;
		_healthBar.Value = _health;
	}

	public override void _Process(double DELTA_)
	{
		if (!_moving)
		{
			if (!_placed)
			{
				if (!_held)
				{
					if (_hovered)
					{
						if (Input.IsActionJustPressed("left_click"))
						{
							Hold();
						}
					}
				}
			}
			else
			{
				if (_selected)
				{
					Vector2 mousePosition = GetGlobalMousePosition();
					LookAt(mousePosition);
					if (Input.IsActionJustReleased("left_click"))
					{
						_selected = false;
						_force = (GlobalPosition - mousePosition) * 100;
						_rotationalForce = 5f;
						_primed = true;
					}
				}
				else if (_hovered)
				{
					if (Input.IsActionJustPressed("left_click"))
					{
						_selected = true;
					}
				}
			}
		}
		else
		{
			// Vector2 towardCenter = (Globals.Instance._screenCenter - GlobalPosition).Normalized();
			// ApplyCentralForce(towardCenter * 100);
			_image.Rotate(_rotationalForce);
			_rotationalForce -= 0.5f / 60;
			if (_rotationalForce <= 0f)
			{
				Stop();
			}
		}
	}

	public override void _PhysicsProcess(double DELTA_)
	{
		if (_held)
		{
			GlobalPosition = GetGlobalMousePosition();
			if (Input.IsActionJustReleased("left_click"))
			{
				Transform2D newTransform = GlobalTransform;
				newTransform.Origin = Position;
				GlobalTransform = newTransform;
				Drop();
			}
		}
	}

	public void ChangeHealth(int CHANGE, Node CHANGEMAKER)
	{
		if (_health <= 0 && CHANGE < 0)
		{
			// knock the piece off the board and out for the round!
			// process on knockout
		}
		_health += CHANGE;
		_healthBar.Value = _health;
		if (_health <= 0)
		{
			Sleeping = true;
			_dead = true;
			_health = 0;
			FireActions(Trigger.On.Death, _manager);
		}
	}


	public void Drop()
	{
		if (_held)
		{
			_held = false;
			_placed = true;
			Freeze = false;
		}
	}

	public void Hold()
	{
		if (_held)
		{
			return;
		}
		Freeze = true;
		_held = true;
	}

	public void Launch()
	{
		GravityScale = 1.0f;
		_moving = true;
		ApplyCentralForce(_force);
		_force = Vector2.Zero;
		_primed = false;
		FireActions(Trigger.On.Launch, _manager);
	}

	public void Stop()
	{
		GravityScale = 0.0f;
		Sleeping = true;
		_moving = false;
		_rotationalForce = 0f;
		FireActions(Trigger.On.Stop, _manager);
	}

	public void FireActions(Trigger.On TRIGGER, Node TARGET = null)
	{
		List<Action> triggeredActions = _Actions.Where(e => e._triggers.IndexOf(TRIGGER) > -1).ToList();
		for (int i = 0; i < triggeredActions.Count; i++)
		{
			triggeredActions[i].Target(TARGET);
			triggeredActions[i].Fire();
		}
		List<Action> expiredActions = _Actions.Where(e => e._triggers.IndexOf(TRIGGER) > -1).ToList();
		_Actions.Except(expiredActions);
	}

	// PRIVATE METHODS
	private void OnMouseEntered()
	{
		_hovered = true;
	}

	private void OnMouseExited()
	{
		_hovered = false;
	}

	private void OnBodyEntered(Node NODE)
	{
		if (NODE is Worker)
		{
			_collisionTarget = NODE;
			FireActions(Trigger.On.Collision, NODE);

			_rotationalForce *= 0.8f;
			Vector2 rotatedForce = LinearVelocity.Rotated(((Worker)NODE)._rotationalForce);

			ApplyCentralForce(rotatedForce);
			_collisionTarget = null;
		}
		else if (NODE is Tchotchke)
		{
			Tchotchke tchotchke = (Tchotchke)NODE;
			tchotchke.FireActions(Trigger.On.Collision, this);
		}
	}

}
