// ============================================================================================= //
//                                            MIXINS                                             //
// ============================================================================================= //

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

///
/// @deprecated Use `emit-custom-props()` mixin instead.
///
/// Emits CSS custom properties declarations from a user-provided theme's tokens transformed
/// with `create-theme-vars()` function.
///
/// @example - scss
///   $theme: (
///     "text-color": darkcyan
///   );
///
///   $theme: create-theme-vars($theme, "button"); -> `("text-color": var(--mg-button-text-color, darkcyan))`
///
///   .foo {
///     @include emit-theme-vars($theme);
///   }
///
/// @example - css
///   .foo {
///     --mg-button-text-color: darkcyan;
///   }
///
/// @param {Map} $tokens - The user-provided theme's tokens map.
///
@mixin emit-theme-vars($tokens) {
    @each $key, $value in $tokens {
        @if $value {
            @if type.is-map($value) {
                @include emit-theme-vars($value);
            } @else {
                @include css.declaration(var.name($value), var.fallback($value));
            }
        }
    }
}

///
/// Emits CSS custom properties declarations from a user-provided theme's tokens.
///
/// @example - scss
///   .foo {
///     @include emit-custom-props((
///       "text-color": darkcyan,
///       "text": (
///         "size": 12px
///       )
///     ), "button");
///   }
///
/// @example - css
///   .foo {
///     --mg-button-text-color: darkcyan;
///     --mg-button-text-size: 12px;
///   }
///
/// @param {Map} $tokens - The user-provided theme's tokens map.
/// @param {String} $component - Component name to prepend for each token's custom property name. Default: `null`.
///
@mixin emit-custom-props($tokens, $component: null) {
    @each $key, $value in $tokens {
        $name: string.combine(variables.$prefix, $component, $key);

        @if $value {
            @if type.is-map($value) {
                @include emit-custom-props($value, string.combine($component, $key));
            } @else {
                @include css.declaration(custom-properties.create($name, $value));
            }
        }
    }
}

///
/// Emits CSS media feature `prefers-color-scheme` declarations.
///
/// @example - scss
///   @include theme.emit-color-scheme("light") {
///     :root {
///       --mg-button-text-color: darkcyan;
///     }
///   }
///
/// @example - css
///   @media (prefers-color-scheme: light) {
///     :root {
///       --mg-button-text-color: darkcyan;
///     }
///   }
///
/// @param {Map} $scheme - The color scheme. Choose between `light` or `dark`.
///
@mixin emit-color-scheme($scheme: "light") {
    $theme: (
        "light",
        "dark"
    );

    @if list.index($theme, $scheme) == null {
        @error "Invalid color scheme, '#{$scheme}' doesn't exist. Choose one of '#{$theme}'.";
    }

    @media (prefers-color-scheme: $scheme) {
        @content;
    }
}

///
/// Config.
///
/// @example - scss
///   @include theme.config("foo");
///
/// @param {String} $prefix - The custom property prefix.
/// @param {String} $color - The custom config of color component.
/// @param {String} $shape - The custom config of shape component.
/// @param {String} $typeface - The custom config of typeface component.
/// @param {String} $typescale - The custom config of typescale component.
///
@mixin config($prefix: null, $color: null, $shape: null, $typeface: null, $typescale: null) {
    @if $prefix {
        variables.$prefix: $prefix;
    }

    @if $color {
        variables.$color: map.deep-merge(variables.$color, $color);
    }

    @if $shape {
        variables.$shape: map.deep-merge(variables.$shape, $shape);
    }

    @if $typeface {
        variables.$typeface: map.deep-merge(variables.$typeface, $typeface);
    }

    @if $typescale {
        variables.$typescale: map.deep-merge(variables.$typescale, $typescale);
    }
}
