using System;
using UnityEngine;

[Serializable]
public struct SpendablePoints<T> where T : ISpendableResource {
    
    [SerializeField] private int _value;
    public int scalar{
        get {return _value;}
    }

    private SpendablePoints(int value) => _value = value;
    public static implicit operator SpendablePoints<T>(int value) => new SpendablePoints<T>(value);
    public static bool operator ==(SpendablePoints<T> a, SpendablePoints<T> b) => (a.scalar == b.scalar);
    public static bool operator >(SpendablePoints<T> a, SpendablePoints<T> b) => (a.scalar > b.scalar);
    public static bool operator <(SpendablePoints<T> a, SpendablePoints<T> b) => (a.scalar < b.scalar);
    public static bool operator !=(SpendablePoints<T> a, SpendablePoints<T> b) => !(a == b);
    public static bool operator >=(SpendablePoints<T> a, SpendablePoints<T> b) => !(a < b);
    public static bool operator <=(SpendablePoints<T> a, SpendablePoints<T> b) => !(a > b);
    public static SpendablePoints<T> operator +(SpendablePoints<T> a, SpendablePoints<T> b) {
        SpendablePoints<T> returnPoints;
        if (a._value > int.MaxValue - b._value) {
            returnPoints = int.MaxValue;
        } else {
            returnPoints = a.scalar + b.scalar;
        }
        return returnPoints;
    } 
    public static SpendablePoints<T> operator -(SpendablePoints<T> a, SpendablePoints<T> b) {
        SpendablePoints<T> returnPoints;
        if (a < b) {
            returnPoints = int.MinValue;
        } else {
            returnPoints = a.scalar - b.scalar;
        }

        return returnPoints;  
    }

    public static float operator /(SpendablePoints<T> a, SpendablePoints<T> b) => (float)a._value / (float)b._value;
    public static SpendablePoints<T> operator /(SpendablePoints<T> a, int b) => a /(float)b; 
    public static SpendablePoints<T> operator /(SpendablePoints<T> a, float b) {
        SpendablePoints<T> returnPoints;

        if (b == 0) {
            returnPoints = int.MaxValue;
        } else {
            returnPoints = (int) (a._value / b);
        }
        
        return returnPoints;
    } 

    public override bool Equals(object obj)
    {
        return obj is SpendablePoints<T> points &&
               scalar == points.scalar;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(scalar);
    }

    public override string ToString() => scalar.ToString();
}


public interface ISpendableResource{};
public class ActionPoints:ISpendableResource{};