#pragma once

#include <cstdint>
#include <string>
#include <variant>

namespace ta::application::config
{
    struct ConfigColorData final
    {
        float r = 1.0f;
        float g = 1.0f;
        float b = 1.0f;
        float a = 1.0f;
    };

    using ConfigValueData = std::variant<std::monostate, bool, int, float, std::string, ConfigColorData>;

    enum class ApplyError : std::uint8_t
    {
        None,
        MissingKey,
        InvalidType,
        InvalidValue,
        DecodeFailed
    };

    struct ApplyResult final
    {
        bool changed = false;
        ApplyError error = ApplyError::None;

        [[nodiscard]] explicit operator bool() const noexcept
        {
            return error == ApplyError::None;
        }
    };

    [[nodiscard]] inline const char* to_string(const ApplyError error) noexcept
    {
        switch (error)
        {
        case ApplyError::None: return "none";
        case ApplyError::MissingKey: return "missing_key";
        case ApplyError::InvalidType: return "invalid_type";
        case ApplyError::InvalidValue: return "invalid_value";
        case ApplyError::DecodeFailed: return "decode_failed";
        default: return "unknown";
        }
    }
}
