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

public abstract class Entity : MonoBehaviour
{
    public int MaxHealth = 100;
    public AudioClip HurtSound;
    public float HurtSoundVolume = 1.0f; 

    private Coroutine currentHurtCoroutine; 
    private Color initialColor;

    private AudioSource audioSource; 
    public AudioSource AudioSource
    {
        get
        {
            return this.audioSource; 
        }
    }

    private Animator animator; 
    public Animator Animator
    {
        get
        {
            return animator; 
        }
    }

    private SpriteRenderer spriteRenderer; 
    public SpriteRenderer SpriteRenderer
    {
        get
        {
            return spriteRenderer; 
        }
    }

    private bool onGround;
    public bool OnGround
    {
        get
        {
            return onGround; 
        }
    }

    private int health;
    public int Health
    {
        get
        {
            return health; 
        }
    }

    public virtual void Die(bool destroyGameObject = true)
    {
        Rigidbody2D rigidbody = this.GetComponent<Rigidbody2D>(); 
        Vector2 velocity = rigidbody != null ? rigidbody.velocity : Vector2.up; 
        CorpseSpawner.Instance.SpawnCorpse(this.transform.position, velocity, Random.Range(3, 5), Random.Range(20.0f, 40.0f));
        if(destroyGameObject)
        {
            GameObject.Destroy(this.gameObject);
        }
    }

    public bool IsDead
    {
        get
        {
            return health <= 0; 
        }
    }

    public virtual void Start()
    {
        this.health = this.MaxHealth;
        this.animator = this.GetComponent<Animator>(); 
        this.spriteRenderer = this.GetComponent<SpriteRenderer>();
        this.audioSource = this.GetComponent<AudioSource>(); 
    }

    public void SetIsOnGround(bool value)
    {
        this.onGround = value;
    }

    private IEnumerator HurtCoroutine(int damage)
    {
        initialColor = this.SpriteRenderer.color; 
        for (int n=1;n<=10;n++)
        {
            float dissortion = Mathf.Abs(Mathf.Sin(((float)n/10) * Mathf.PI));
            this.SpriteRenderer.color = new Color(initialColor.r, initialColor.g-dissortion, initialColor.b-dissortion, initialColor.a);
            yield return new WaitForEndOfFrame(); 
        }
        this.SpriteRenderer.color = initialColor; 
        this.currentHurtCoroutine = null; 
    }

    public void Harm(int damage, Entity attacker, Vector3 fromPosition) 
    {
        if(!IsDead)
        {
            SetHealth(health - damage);
            if (HurtSound != null && audioSource != null)
            {
                audioSource.PlayOneShot(HurtSound, HurtSoundVolume);
            }
            if (this.currentHurtCoroutine != null)
            {
                StopCoroutine(this.currentHurtCoroutine);
                this.SpriteRenderer.color = initialColor;
            }
            this.currentHurtCoroutine = StartCoroutine(HurtCoroutine(damage));
        }
    }

    public void SetHealth(int newHealth)
    {
        int healthBefore = health; 
        health = Mathf.Clamp(newHealth, 0, MaxHealth); 
        if (health <= 0 && healthBefore > 0) 
        {
            Die();
        }
    }

}
