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

public class FighterZombie : MobBase
{
    public override LevelObjectFaction ObjectFaction { get { return LevelObjectFaction.Zombie; } }
    public override LevelObjectType ObjectType { get { return LevelObjectType.Zombie; } }

    public int wanderDistance = 5;
    public float maxRange = 21.0f;
    public AudioSource attackSound;
    private int facing;
    private bool searchingForEnemies = false;
    private float spawnPosition;
    private GameObject target = null;
    private bool wandering = true;
    private SpriteRenderer zombieSpriteRenderer;
    private bool attacking = false;
    private float attackTimeout;

    void Awake()
    {
        Init();
    }

    public override void Init()
    {
        base.Init();
        zombieSpriteRenderer = GetComponent<SpriteRenderer>();
        spawnPosition = transform.position.x;
        System.Random rnd = new System.Random();
        facing = (int)rnd.Next(0, 2);

        if (facing == 0) {
            facing = -1;
            zombieSpriteRenderer.flipX = false;
        }
        else
        {
            zombieSpriteRenderer.flipX = true;
        }
    }

    public void SearchComplete(GameObject newTarget)
    {
        searchingForEnemies = false;
        if (newTarget != null)
        {
            wandering = false;
            target = newTarget;
        }
    }

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (paused) return;

        if (attacking && Time.time >= attackTimeout)
        {
            attacking = false;

        }

        //Check to see if should play random sound
        System.Random rnd = new System.Random();
        if (!IsPlayingRandomSound() && rnd.Next(100) < 1) //1% chance per update cycle...
        {
            EventManager.TriggerMobRandomSoundRequest(this);
        }

        if (wandering && !searchingForEnemies)
        {
            searchingForEnemies = true;

            //Check to see if there's any enemies to engage
            EventManager.TriggerSeekEnemy(this);
        }

        if (wandering)
        {
            WanderAction();
            return;
        }

        var enemyContacts = ContactObjects.Where(o => o.ObjectFaction == LevelObjectFaction.Human);
        if (enemyContacts.Any())
        {
            if (!attacking)
            {
                if (AttackAction(enemyContacts)) return;
            }
            return;
        }

        //If Target is active
        if (target != null)
        {
            SeekAction();
            return;

        }

        //Return to wandering
        wandering = true;
        spawnPosition = transform.position.x;
    }

    private bool AttackAction(IEnumerable<LevelObjectBase> enemyContacts)
    {
        Debug.Log($"{this.name}: Attacking");
        var target = enemyContacts.FirstOrDefault(o => !o.Destroyed);
        if (target != null)
        {
            attacking = true;
            attackTimeout = Time.time + AttackCooldownInSeconds;
            //animator.SetTrigger("KnightAttack");
            //attackSound.Play();
            target.TakeDamage(this, Damage);
            return true;
        }

        return false;
    }

    private void SeekAction()
    {
        if (transform.position.x - target.transform.position.x < 0)
        {
            facing = 1;
            zombieSpriteRenderer.flipX = true;

            float newX = transform.position.x + (Speed * Time.deltaTime);
            if (newX > maxRange)
            {
                //Prevent zombie from going out of bounds
                return;
            }

            transform.Translate(Vector3.right * (Speed * Time.deltaTime));
        }
        else
        {
            facing = -1;
            zombieSpriteRenderer.flipX = false;

            float newX = transform.position.x + (-1 * Speed * Time.deltaTime);
            if (newX < (-1 * maxRange))
            {
                //Prevent zombie from going out of bounds
                return;
            }

            transform.Translate(Vector3.left * (Speed * Time.deltaTime));
        }

    }

    private void WanderAction()
    {
        //Prevent zombie from going out of bounds
        float newX = transform.position.x + (facing * Speed * Time.deltaTime);
        if (newX > maxRange || System.Math.Abs(transform.position.x) >= wanderDistance)
        {
            facing *= -1;
        }
        if (facing < 0)
        {
            zombieSpriteRenderer.flipX = false;
            transform.Translate(Vector3.left * (Speed * Time.deltaTime));
        }
        else
        {
            zombieSpriteRenderer.flipX = true;
            transform.Translate(Vector3.right * (Speed * Time.deltaTime));
        }
    }
}
