using System;
using UnityEngine;

public class Health : MonoBehaviour
{
    [SerializeField] private int maxHealth = 100;
    [SerializeField] private DamagePopup damagePopupPrefab;
    public int CurrentHealth { get; private set; }
    
    public event Action OnDeath;
    public event Action<int> OnHealthChanged;
    public event Action OnScoreDecreased;
    
    [SerializeField] private GameObject retryMessage;

    private void Awake()
    {
        if (retryMessage != null) retryMessage.SetActive(false);
        CurrentHealth = maxHealth;
    }

    public void TakeDamage(int amount)
    {
        if (gameObject.CompareTag("Player"))
        {
            FindFirstObjectByType<CinemachineShakeService>().Shake(5f, 10f, 0.01f);
        }

        if (amount <= 0 || CurrentHealth <= 0) return;  // if the character is already dead, don't destroy the object and cause a null pointer exception
        CurrentHealth -= amount; // the character takes the damage
        SpawnDamagePopup(amount);
        OnHealthChanged?.Invoke(CurrentHealth);
        OnScoreDecreased?.Invoke();

        if (CurrentHealth <= 0)
        {
            CurrentHealth = 0;
            Die();
        }
    }

    private void Die()
    {
        if (retryMessage != null)
        {
            retryMessage.SetActive(true);
            Time.timeScale = 0f;
            //set player prefs
            PlayerPrefs.SetInt("numberIdx", 0);
            PlayerPrefs.SetFloat("fillAmount", 0);
        }
        OnDeath?.Invoke();
        if (gameObject.GetComponentInChildren<EnemyAnimation>() != null)
        {
            FindFirstObjectByType<CinemachineShakeService>().Shake(5f, 1f, 0.03f);
            gameObject.GetComponent<EnemyCombat>().DisableHitBox();
            gameObject.GetComponentInChildren<EnemyAnimation>().SetDeathTrigger();
        }
        
        Destroy(gameObject, 1f); // this float delays the destroyal of the object for the animation before the death
    }

    public void SetMaxHealth(int healthAmount)
    {
        maxHealth = healthAmount;
    }

    public int GetMaxHealth()
    {
        return maxHealth;
    }

    public void RefillHealth()
    {
        CurrentHealth = maxHealth;
    }

    private void SpawnDamagePopup(int damage)
    {
        Vector3 spawnPos = transform.position + Vector3.up * 1.5f;
        DamagePopup popup = Instantiate(damagePopupPrefab, spawnPos, Quaternion.identity);
        popup.Init(damage);
    }
}
