#nullable enable
using NaughtyAttributes;
using UnityEngine;
using UnityEngine.InputSystem;

public class MinionThrower : MonoBehaviour {
	[SerializeField] [Required]
	Arena arena = null!;
	[SerializeField] [Required]
	GameFlowManager gameFlowManager = null!;
	[SerializeField] [Required]
	PlayerStats playerStats = null!;

    public Entity[] minionPrefabs;
    public GameObject aimArrow;

    bool isInThrowMode;
    Vector2 throwDirection;
    MinionBar minionBar;
    VampireEntity vampireEntity;
    PlayerMovement movement;
    float currentCooldownTimer;
    float currentInitialCooldown;

    void Awake() {
        vampireEntity = GetComponent<VampireEntity>();
        movement = GetComponent<PlayerMovement>();
        minionBar = FindObjectOfType<MinionBar>();
        aimArrow.SetActive(false);
    }

    void Start() {
        foreach (Entity minion in minionPrefabs) {
            minionBar.AddMinionType(minion);
        }
    }

    void FixedUpdate() {
        if (currentCooldownTimer > 0f) {
            currentCooldownTimer -= Time.fixedDeltaTime;
            minionBar.UpdateReload(currentCooldownTimer / currentInitialCooldown);
        }
    }

    public void ToggleThrowMode(InputAction.CallbackContext context) {
        if (!gameFlowManager.CanDoAction)
            return;

        if (context.performed) {
            isInThrowMode = true;
            aimArrow.SetActive(true);
        } else if (context.canceled && throwDirection.magnitude >= playerStats.MinJoystickValueForThrowing) {
            PerformThrow();
            isInThrowMode = false;
            aimArrow.SetActive(false);
        }
    }

    public void AimThrow(InputAction.CallbackContext context) {
	    if (!gameFlowManager.CanDoAction)
		    return;
	    
        throwDirection = context.ReadValue<Vector2>();
        if (throwDirection.sqrMagnitude > 1f)
	        throwDirection.Normalize();
        
        if (vampireEntity.playerMovement.facingRight) {
            aimArrow.transform.rotation = Quaternion.FromToRotation(Vector2.right, throwDirection);
        } else {
            aimArrow.transform.rotation = Quaternion.FromToRotation(Vector2.left, throwDirection);
        }
    }

    void PerformThrow() {
        if (!isInThrowMode || currentCooldownTimer > 0f) {
            return;
        }

        float minionHealthCost = 10f; // TODO
        if (minionHealthCost >= vampireEntity.Health) {
            return;
        }
        vampireEntity.TakeDamage(minionHealthCost, vampireEntity);

        currentInitialCooldown = 2f; // TODO
        currentCooldownTimer = currentInitialCooldown;
        minionBar.UpdateReload(currentCooldownTimer / currentInitialCooldown);

        var newMinion = Instantiate(minionBar.GetCurrentMinion().gameObject, arena.minionParent)
            .GetComponent<Monster>();
        newMinion.arena = arena;
        if (throwDirection == Vector2.zero)
	        Debug.LogWarning("Throwing with a null throwDirection.");
        Vector2 normalizedDirection = throwDirection.normalized;
        newMinion.transform.position = transform.position + (Vector3)normalizedDirection;
        newMinion.direction = normalizedDirection;
        newMinion.gameFlowManager = vampireEntity.gameFlowManager;
        
        if (movement.GetSafeZoneIfImmobile() is { } safeZone) {
            newMinion.thrownFromSafeZone = true;
            newMinion.thrownTargetPosition = safeZone.GetOutsidePosition(normalizedDirection);
        }
    }

}
