using System;
using R3;
using UnityEngine;

namespace KitsuneCafe.Entities
{
  public record HealthChanged(int Previous, int Current)
  {
    public static implicit operator HealthChanged((int, int) t) => new(t.Item1, t.Item2);
    public static implicit operator (int Previous, int Current)(HealthChanged t) =>
      (t.Previous, t.Current);
  }

  public class Health : MonoBehaviour, IDamageable
  {
    [SerializeField]
    private SerializableReactiveProperty<int> max;

    public int Max => max.CurrentValue;

    [SerializeField]
    private SerializableReactiveProperty<int> current;

    public int Current => current.CurrentValue;

    [SerializeField]
    private bool restoreOnStart = true;

    public event EventHandler<HealthChanged> HealthChanged;

    private void Start()
    {
      if (restoreOnStart)
      {
        current.Value = max.Value;
      }

      current.AsObservable()
        .Pairwise()
        .Subscribe(t => HealthChanged?.Invoke(this, t));
    }

    public void Recover(int amount)
    {
      current.Value = Math.Clamp(Current + amount, 0, Max);
    }

    public void ReceiveDamage(IDamaging source, int amount)
    {
      current.Value = Math.Clamp(Current - amount, 0, Max);
    }
  }
}
