namespace Service;

public interface IConfigService
{
    /// <summary>
    /// 根据Key获取配置值
    /// </summary>
    Task<T?> GetConfigByKeyAsync<T>(string key);

    /// <summary>
    /// 设置配置值
    /// </summary>
    Task<bool> SetConfigByKeyAsync<T>(string key, T value);
}

public class ConfigService(IConfigRepository configRepository) : IConfigService
{
    public async Task<T?> GetConfigByKeyAsync<T>(string key)
    {
        var config = await configRepository.GetByKeyAsync(key);
        if (config == null || string.IsNullOrEmpty(config.Value))
        {
            return default;
        }

        return config.Type switch
        {
            ConfigType.Boolean => (T)(object)bool.Parse(config.Value),
            ConfigType.String => (T)(object)config.Value,
            ConfigType.Number => (T)Convert.ChangeType(config.Value, typeof(T)),
            ConfigType.Json => JsonSerializer.Deserialize<T>(config.Value) ?? default,
            _ => default
        };
    }

    public async Task<bool> SetConfigByKeyAsync<T>(string key, T value)
    {
        if (value == null)
        {
            return false;
        }

        var config = await configRepository.GetByKeyAsync(key);
        var type = typeof(T) switch
        {
            Type t when t == typeof(bool) => ConfigType.Boolean,
            Type t when t == typeof(int)
                || t == typeof(double)
                || t == typeof(float)
                || t == typeof(decimal) => ConfigType.Number,
            Type t when t == typeof(string) => ConfigType.String,
            _ => ConfigType.Json
        };
        var valueStr = type switch
        {
            ConfigType.Boolean => value.ToString()!.ToLower(),
            ConfigType.Number => value.ToString()!,
            ConfigType.String => value as string ?? string.Empty,
            ConfigType.Json => JsonSerializer.Serialize(value),
            _ => throw new InvalidOperationException("Unsupported config type")
        };
        if (config == null)
        {
            config = new ConfigEntity
            {
                Key = key,
                Type = type,

            };
            return await configRepository.AddAsync(config);
        }

        config.Value = valueStr;
        config.Type = type;
        return await configRepository.UpdateAsync(config);
    }
}
