// ============================================================================================= //
//                                           FUNCTIONS                                           //
// ============================================================================================= //

@use "sass:list";
@use "sass:map";
@use "@unsass/string";
@use "@unsass/types" as type;
@use "@unsass/var";
@use "./variables";

///
/// Create a name with the global config prefix.
///
/// @param {Arglist} $name - A list of strings.
///
/// @return {String} The generated prefixed name.
///
@function create-name($name...) {
    @return string.combine(variables.$prefix, $name...);
}

///
/// Validates a user-provided theme's token and throws an error if tokens are invalid.
///
/// @param {List|Map} $refs - A list of supported tokens.
/// @param {Map} $tokens - The user-provided theme's tokens map.
/// @param {String} $component - The component name.
///
/// @return {Map} The validated theme map.
///
@function validation($refs, $tokens, $component: null) {
    $supported-tokens: if(type.is-map($refs), map.keys($refs), $refs);
    $unsupported-tokens: ();

    @each $token, $value in $tokens {
        @if list.index($supported-tokens, $token) == null {
            $unsupported-tokens: list.append($unsupported-tokens, $token, $separator: comma);
        }
    }

    @if list.length($unsupported-tokens) > 0 {
        @error "The following tokens are not supported: '#{$unsupported-tokens}'. The supported theme tokens are: '#{$supported-tokens}'";
    }

    @return $tokens;
}

///
/// Transforms a user-provided theme's tokens map values into a `var()` custom properties.
///
/// @example - scss
///   $theme: theme.create-theme-vars((
///     "text-color": darkcyan,
///     "text": (
///       "size": 12px
///     )), "button");
///
/// @example - scss
///   $theme: (
///     "text-color": var(--mg-button-text-color, darkcyan),
///     "text": (
///       "size": var(--mg-button-text-size, 12px)
///     )
///   );
///
/// @param {Map} $tokens - The user-provided theme's tokens map.
/// @param {String} $prefix - Component's name to prepend for each token's custom property name.
///                           Set to `false` for disabled.
///
/// @return {Map} The transformed theme map.
///
@function create-theme-vars($tokens, $prefix) {
    @each $key, $value in $tokens {
        @if $value != null {
            $token: create-name($prefix, $key);

            @if type.is-map($value) {
                $value: create-theme-vars($value, string.combine($prefix, $key));
            } @else {
                $value: var.create($token, $value);
            }

            $tokens: map.set($tokens, $key, $value);
        }
    }

    @return $tokens;
}

///
/// Emits CSS variable declaration from a user-provided theme's.
///
/// @example - scss
///   .foo {
///     color: theme.emit-variable((
///       "text-color": darkcyan
///     ), "text-color", false, "button");
///   }
///
/// @example - css
///   .foo {
///     color: var(--mg-button-text-color);
///   }
///
/// @param {Map} $tokens - The user-provided theme's tokens map.
/// @param {String} $token - The theme token key.
/// @param {Boolean} $fallback - Allow to display the CSS variable fallback.
/// @param {String} $prefix - Token's prefix name to prepend for each token's custom property name.
///
@function emit-variable($tokens, $token, $fallback: false, $prefix: null) {
    $value: map.get($tokens, $token);
    $token: create-name($prefix, $token);

    @if $fallback {
        @return var.create($token, $value);
    }

    @return var.create($token);
}
