using Newtonsoft.Json;
using System;

namespace Pilz.Configuration;

[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(SettingsValueOptionJsonConverter))]
public class SettingsValueOption<T> : ISettingsValueOptionValueAccessor where T : struct
{
    protected T? value;

    public T DefaultValue { get; }
    public virtual bool IsDefault => value == null;

    public SettingsValueOption()
    {
    }

    public SettingsValueOption(T value)
    {
        DefaultValue = value;
    }

    public virtual T Value
    {
        get => value ?? DefaultValue;
        set => this.value = value;
    }

    public static implicit operator T(SettingsValueOption<T> option)
    {
        return option.Value;
    }

    object ISettingsValueOptionValueAccessor.ValueRaw
    {
        get => value;
        set
        {
            if (value is not null)
                this.value = Convert.ChangeType(value, typeof(T)) as T?;
            else
                this.value = null;
        }
    }

    public virtual void Reset()
    {
        value = null;
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}
