namespace SharpChat.Configuration;

public class CachedValue<T>(Config config, string name, TimeSpan lifetime, T? fallback) {
    private Config Config { get; } = config ?? throw new ArgumentNullException(nameof(config));
    private string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
    private object ConfigAccess { get; } = new();

    private object? CurrentValue { get; set; } = default(T);
    private DateTimeOffset LastRead { get; set; }

    public T? Value {
        get {
            lock(ConfigAccess) { // this lock doesn't really make sense since it doesn't affect other config calls
                DateTimeOffset now = DateTimeOffset.Now;
                if((now - LastRead) >= lifetime) {
                    LastRead = now;
                    CurrentValue = Config.ReadValue(Name, fallback);
                }
            }
            return (T?)CurrentValue;
        }
    }

    public static implicit operator T?(CachedValue<T?> val) => val.Value;

    public void Refresh() {
        LastRead = DateTimeOffset.MinValue;
    }

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