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

public class DestructibleObject : MonoBehaviour
{
    public static DestructibleObject Get(GameObject go)
    {
        return go?.GetComponent<DestructibleObject>();
    }

    public static DestructibleObject Get(Collider c)
    {
        if (c == null)
            return null;

        if (c.GetComponent<DestructibleObject>())
            return c.GetComponent<DestructibleObject>();

        return c.attachedRigidbody?.GetComponent<DestructibleObject>();
    }

    public static DestructibleObject Get(Rigidbody2D rb)
    {
        if (rb == null)
            return null;

        return rb.GetComponent<DestructibleObject>();
    }

    public event Action<DestructibleObject, DamageInfo> OnDamaged = delegate { };
    public event Action<DestructibleObject, DamageInfo> OnHealed = delegate { };
    public event Action<DestructibleObject, DamageInfo> OnDestroyed = delegate { };
    public event Action<DestructibleObject, int> OnHPChanged = delegate { };
    public event Action<DestructibleObject> OnRevived = delegate { };

    public int HP = 0;
    [Range(1, 9999)]
    public int maxHP = 10;
    [Tooltip("Set autoDestroy >= 0 to automatically destroy GameObject after duration")]
    public float autoDestroy = -1;

    public bool Dead => HP <= 0;
    public bool Alive => HP > 0;
    public bool FullHP => HP == maxHP;
    public float NormalizedHP => (float)HP / (float)maxHP;

    internal virtual void Start()
    {
        if (HP == 0 || HP > maxHP)
            HP = maxHP;
    }

    //TODO: handle relevant information about what/who/where did the damage
    public void Damage(DamageInfo info)
    {
        if (Dead)
            return;

        HP -= info.amount;

        if (HP < 0)
            HP = 0;

        OnDamaged(this, info);
        OnHPChanged(this, HP);

        if (HP <= 0)
        {
            OnDestroyed(this, info);

            if (autoDestroy >= 0)
                Destroy(gameObject, autoDestroy);
        }
    }

    public void Heal(DamageInfo info)
    {
        if (Dead)
            return;

        HP += info.amount;

        if (HP > maxHP)
            HP = maxHP;

        OnHealed(this, info);
        OnHPChanged(this, HP);
    }

    public void Revive()
    {
        if (Alive)
            return;

        HP = 1;
        OnHPChanged(this, HP);
        OnRevived(this);
    }
}
