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);
                        Logger.Debug($"Read {Name} ({CurrentValue})");
                    }
                }
                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;
        }
    }
}