using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Health))]
[RequireComponent(typeof(Animator))]
public class Player : MonoBehaviour
{
    [SerializeField] private float attackRadius = 2f;
    [SerializeField] private float attackDistance = 2f;
    [SerializeField] private float speed = 2f;
    [SerializeField] LayerMask foodLayers;
    
    Health health;
    Rigidbody2D rb;
    Animator anim;
    
    private Vector3 lastMoveDirection = Vector2.down;
    private bool isDef = false;
    private bool isAttacking = false;
    private bool isMoving = false;

    private Vector3 AttackPosition
    {
        get
        {
            return transform.position + lastMoveDirection * attackDistance;
        }
    }

    private bool CanProcessInput()
    {
        return !health.IsDead;
    }
    
    void Start()
    {
        health = GetComponent<Health>();
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if(GameManager.Instance.IsWinScore)
            return;
        
        if(!isMoving)
            HandleDefendMode();

        if (!isDef && !isAttacking)
        {
            HandleAttack();
            HandleCharacterMovement();
        }
            
    }

    void HandleAttack()
    {
        if (CanProcessInput() && Input.GetKeyDown(KeyCode.Space))
        {
            isAttacking = true;
            anim.SetTrigger("Attack");
        }
    }
    void HandleDefendMode()
    {
        if (CanProcessInput() && Input.GetKeyDown(KeyCode.C))
        {
            isDef = !isDef;
            anim.SetBool("Def", isDef);
        }
    }
    
    void HandleCharacterMovement()
    {
        rb.MovePosition(rb.position + GetMoveInput() * (speed * Time.fixedDeltaTime));
    }
    public Vector2 GetMoveInput()
    {
        if (CanProcessInput())
        {
            Vector2 move = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
            move = move.normalized;
            isMoving = move.sqrMagnitude > 0.01f;

            if (isMoving)
            {
                lastMoveDirection = move;
                anim.SetFloat("Horizontal", move.x);
                anim.SetFloat("Vertical", move.y);
            }
            anim.SetBool("Movement", move.sqrMagnitude > 0.01f);
            
            return move;
        }

        return Vector2.zero;
    }
    
    public void Attack()
    {
        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPosition, attackRadius, foodLayers);

        foreach (Collider2D enemy in hitEnemies)
        {
            enemy.GetComponent<Health>()?.TakeDamage(10);
        }
    }

    public void OnAttackAnimationEnd()
    {
        Attack();
        isAttacking = false;
    }
    
    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(AttackPosition, attackRadius);
    }
}
