using Microsoft.Extensions.Configuration;

namespace Kit.Helpers
{
    public interface IConfigurationItem
    {
        DateTime FillDate { get; set; }

        void Init(IConfiguration configuration);
    }

    public class ConfigurationHelper
    {
        private readonly string _prefix;
        private readonly IConfiguration _configuration;

        public ConfigurationHelper(IConfiguration configuration) : this(configuration, string.Empty)
        {
            _configuration = configuration;
        }

        public ConfigurationHelper(IConfiguration configuration, string prefix)
        {
            _configuration = configuration;
            _prefix = prefix;
        }

        private string CreateKey(string itemKey)
        {
            return string.IsNullOrEmpty(_prefix)
                   ? itemKey.ToString()
                   : $"{_prefix}:{itemKey}";
        }

        public string GetConnectionString(string name, bool required = true)
        {
            string connectionStringName = this.CreateKey(name);

            string connectionString = _configuration.GetConnectionString(connectionStringName);

            if (required)
            {
                Check.StringArgumentIsNotNullOrEmpty(connectionString, null, $"connection string not set in config. name={connectionStringName}");
            }

            return connectionString;
        }

        public string GetAppSettingValue(object settingsItemKey, bool required = true, string? defaultValue = null)
        {
            // create key
            string appSettingsKey = this.CreateKey(settingsItemKey?.ToString() ?? string.Empty);

            // read
            string? configurationValue = _configuration[appSettingsKey] ?? defaultValue;

            // validate
            if (required && string.IsNullOrWhiteSpace(configurationValue))
            {
                throw new Exception($"{appSettingsKey} not set in appSettings section");
            }

            return configurationValue ?? string.Empty;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="required"></param>
        /// <exception cref="InvalidOperationException"></exception>
        /// <returns>The <see cref="IConfigurationSection"/>.</returns>
        public IConfigurationSection GetSection(string name, bool required = true)
        {
            // create key
            string appSettingsKey = this.CreateKey(name.ToString());

            if (required)
            {
                return _configuration.GetRequiredSection(appSettingsKey);
            }
            else
            {
                return _configuration.GetSection(appSettingsKey);
            }
        }

        public TEntity? Get<TEntity>(string name)
        {
            // create key
            string key = this.CreateKey(name.ToString());

            return _configuration.GetSection(key).Get<TEntity>();
        }
    }
}