using Kryz.CharacterStats.Examples;
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class Health : Resource
{
    protected CharacterStats character;

    protected AbsorbEffectInstance absorbEffectInstance;
    protected DamageIncomeModifierEffectInstance damageIncomeModifierEffectInstance;

    public UnityEvent<float> onMaxHealthChanged = new UnityEvent<float>();
    public UnityEvent onDeath = new UnityEvent();

    [HideInInspector]
    public PhotonView photonView;

    float incomingValue;
    float percentMitigation;
    float absorbResult;

    protected virtual void Awake()
    {
        character = GetComponent<CharacterStats>();
        photonView = GetComponent<PhotonView>();
        absorbEffectInstance = GetComponent<AbsorbEffectInstance>();
        damageIncomeModifierEffectInstance = GetComponent<DamageIncomeModifierEffectInstance>();


        baseMaxValue = maxValue;
        baseFlatRegen = flatRegen;

        character.onUpdateStatValues.AddListener(CalculateMaxValueBasedOnStat);
    }

    protected override void Start()
    {
        if (!photonView.IsMine) return;

        base.Start();
    }


    protected void HandleDamageIncomeModifierEffects()
    {
        if (incomingValue < 0)
        {
            percentMitigation = 0;

            if (damageIncomeModifierEffectInstance.IsActive)
            {
                Debug.Log("Incoming damage b4 mitigation: " + incomingValue);

                incomingValue = damageIncomeModifierEffectInstance.ModifyDamageIncome(incomingValue);

                if (incomingValue > 0) //avoid damage ultra mitigated turning into healing
                    incomingValue = 0;
            }
            Debug.Log("Incoming damage after mitigation: " + incomingValue);
        }
    }

    protected void HandleAbsorbEffects()
    {
        if (incomingValue < 0)
        {
            if (absorbEffectInstance.IsActive)
            {
                Debug.Log("Incoming damage b4 absorbs: " + incomingValue);

                incomingValue = absorbEffectInstance.AbsorbDamage(incomingValue);

                if (incomingValue > 0) //avoid complete absorbs turning into healing
                    incomingValue = 0;
            }
            Debug.Log("Incoming damage after absorbs: " + incomingValue);
        }
    }

    public override void ChangeValue(float value)
    {
        if (!photonView.IsMine) return;
        //Debug.Log("Value to change: " + value);
        incomingValue = value;

        HandleDamageIncomeModifierEffects();

        HandleAbsorbEffects();

        currentValue += incomingValue;

        currentValue = Mathf.Clamp(currentValue, 0, maxValue);
        if (currentValue == 0)
        {
            //dead;
            onDeath.Invoke();
        }
        //Debug.Log("CurrentHealth: " + currentValue);
        onResourceChanged.Invoke(currentValue);
    }

    public bool EnoughHealth(float cost)
    {
        return cost <= currentValue;
    }


    [PunRPC]
    public void RPC_ChangeValueHealth(float value)
    {
        if (!photonView.IsMine) return;
        Debug.Log("Received ChangeValue from RPC from someone");
        ChangeValue(value);
    }

    public override float GetMaxValue()
    {
        return base.GetMaxValue();
    }

    public virtual void CalculateMaxValueBasedOnStat()
    {
        maxValue = baseMaxValue + character.Vitality.Value * 10f;

        CalculateRegenValueBasedOnStat();

        onMaxHealthChanged.Invoke(maxValue);
    }
    public void CalculateRegenValueBasedOnStat()
    {
        flatRegen = baseFlatRegen + (character.Strength.Value - character.Strength.BaseValue) * 0.5f;
        percentRegen = (character.Vitality.Value - character.Vitality.BaseValue) * 0.01f;
    }

    public override void SetMaxValue(float value)
    {
        base.SetMaxValue(value);

        onMaxHealthChanged.Invoke(maxValue);
    }


}
