using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AntiPlayer : Fighter, IFighterCallback
{

    [SerializeField, Tooltip("How close the AntiPlayer has to be to start attacking, or how far away it has to be to start running towards the target")]
    float maxDistanceToEnemy = 1f;
    [SerializeField] float movementSpeed = 4f;
    [SerializeField, Tooltip("After killing an Enemy, how long to stay idle before targeting the next enemy")]
    float delayUntilNextTarget = 0.3f;

    string[] attackAnimationTriggers = new string[] { "Attack1", "Attack2", "Attack3" };
    List<Fighter> enemies = new List<Fighter>();
    Fighter currentTargetEnemy;

    protected override void Awake()
    {
        base.Awake();
        fighterType = FighterTypes.ANTI_PLAYER;
        opponentTag = "Enemy";
        animator.SetBool("Grounded", true);
    }

    protected override void Update()
    {
        base.Update();
        if (!alive || currentTargetEnemy == null)
        {
            return;
        }

        var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
        var scale = transform.localScale;
        // Always face the target Enemy
        scale.x = vectorToNextEnemy.x < 0 ? -initalScale.x : initalScale.x;
        transform.localScale = scale;

        // Run towards target enemy if too far away
        if (Mathf.Abs(vectorToNextEnemy.x) > maxDistanceToEnemy)
        {
            animator.SetInteger("AnimState", 1); // Run
            rigidbody.velocity = new Vector2(Mathf.Sign(vectorToNextEnemy.x) * movementSpeed, rigidbody.velocity.y);
        } else
        {
            animator.SetInteger("AnimState", 0);
            rigidbody.velocity = new Vector2(0, rigidbody.velocity.y);
        }
    }
    protected override bool CanAttack()
    {
        if (currentTargetEnemy == null)
        {
            return false;
        }
        // Can only attack when near an Enemy
        var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
        return Mathf.Abs(vectorToNextEnemy.x) <= maxDistanceToEnemy;
    }

    protected override void Attack()
    {
        animator.SetTrigger(attackAnimationTriggers[Random.Range(0, attackAnimationTriggers.Length)]);
    }

    void CalculateClosestEnemy()
    {
        enemies.Sort((a, b) => (int)Mathf.Sign(Vector3.Distance(transform.position, a.transform.position) - Vector3.Distance(transform.position, b.transform.position)));
        currentTargetEnemy = enemies.Count > 0 ? enemies[0] : null;
    }

    public override int DealDamage(int dmg)
    {
        var actualDamage = base.DealDamage(dmg);
        StatsManager.instance.ModifyMana((int)(actualDamage * StatsManager.instance.manaReceiveMultiplier));
        return actualDamage;
    }

    public void OnFighterDeath(Fighter fighter)
    {
        enemies.Remove(fighter);
        // Wait a short time before targeting next enemy. This is to avoid interrupting the current
        // attack animation, which would happen if we immediately ran to the next target.
        currentTargetEnemy = null;
        Invoke(nameof(CalculateClosestEnemy), delayUntilNextTarget);
    }

    public override void OnRoundStart()
    {
        base.OnRoundStart();

        foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
        {
            var fighter = enemy.GetComponent<Fighter>();
            fighter.callbacks.Add(this);
            enemies.Add(fighter);
        }
        CalculateClosestEnemy();
    }

    public override void OnRoundEnd()
    {
        base.OnRoundEnd();

        enemies.Clear();
        currentTargetEnemy = null;
    }
}