////
/// @group themes
/// Core configuration module for the themes system. 
/// Used to orchestrate custom property variations (e.g., light/dark modes).
/// - Note: This system is intended for switching context values like colors, box-shadows, and borders. 
///   It is not recommended to use this for structural layout values like margins or padding. 
///   For responsive or structural changes, rely on the layout/breakpoint modules or component modifiers.
////

@use "sass:map";
@use "sass:list";
@use "sass:meta";
@use "utils";
@use "cssvar";

/// Module Settings
/// @type Map
/// @prop {String} default ["light"] The theme key output to :root
/// @prop {Map} color-schemes [()] Maps theme names to their corresponding valid CSS color-scheme value (e.g. ("high-contrast": "dark")). Note: If a theme name is literally "light" or "dark", it does not need to be mapped here.
/// @prop {Map} inverses [()] Maps theme names to their opposite theme name (e.g. ("light": "dark", "dark": "light")). Used to output the .theme-inverse utility.
$config: (
  "default" : "light",
  "color-schemes" : (),
  "inverses" : ()
) !default;

/// The themes map
/// - Format: `("property-name": ("light": value, "dark": value))`
/// @type Map

$tokens: () !default;

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.themes-set(( "default" : "dark" ));

@mixin set($changes) {
  $config: map.merge($config, $changes) !global;
}

/// Set the theme variations
/// @param {Map} $changes Map of theme variations to merge
/// @param {String} $merge-mode Merge mode see utils.map-merge() [null|"deep"|"overwrite"]
/// @example scss
///   @include ulu.themes-set-tokens((
///     "color-background": (
///       "light": white,
///       "dark": black
///     )
///   ));

@mixin set-tokens($changes, $merge-mode: "deep") {
  $tokens: utils.map-merge($tokens, $changes, $merge-mode) !global;
}

/// Get a config option
/// @param {String} $name Name of property
/// @example scss {compile} Example usage
///   .test {
///     content: ulu.themes-get("default");
///   }
/// @return {*} Resolved value 

@function get($name) {
  @return utils.require-map-get($config, $name, "themes [config]");
}

/// Helper function to safely get the color scheme
/// @param {String} $theme-name The name of the theme to lookup
/// @example scss {compile} Example usage
///   .test {
///     content: ulu.themes-get-color-scheme("dark");
///   }
/// @return {String|Null} The CSS color-scheme value or null

@function get-color-scheme($theme-name) {
  $schemes: get("color-schemes");
  $mapped: map.get($schemes, $theme-name);

  @if ($mapped) {
    @return $mapped;
  }

  @if ($theme-name == "light" or $theme-name == "dark") {
    @return $theme-name;
  }

  @warn "ULU Themes: No valid color-scheme mapped for theme '#{$theme-name}'. Please add it using `themes.set(( \"color-schemes\" : ( \"#{$theme-name}\": \"light|dark\" ) ))`. The `color-scheme` property will not be output for this theme.";
  @return null;
}

/// Helper function to get all unique theme keys (e.g., 'light', 'dark') from the $themes map
/// @return {List} A list of all unique theme string keys

@function get-keys() {
  $keys: ();
  @each $prop, $theme-map in $tokens {
    @if meta.type-of($theme-map) == 'map' {
      @each $key, $val in $theme-map {
        @if not list.index($keys, $key) {
          $keys: list.append($keys, $key);
        }
      }
    }
  }
  @return $keys;
}

/// Outputs css vars for a specific type from a theme map
/// @param {String} $key The key used to retrieve values from the map.
/// @param {Map} $tokens [$tokens] The map containing the values. Defaults to the internal $tokens map.
/// @param {String} $prefix The optional prefix for CSS variables.
/// @example scss {compile} Example usage
///   @include ulu.themes-set-tokens((
///     "color-background": (
///       "light": white,
///       "dark": black
///     )
///   ));
///   :root {
///     @include ulu.themes-declare("light");
///   }

@mixin declare($key, $tokens: $tokens, $prefix: cssvar.get("prefix")) {
  @each $name, $definition in $tokens {
    $value: map.get($definition, $key);
    @if ($value != null) {
      @include cssvar.declare($name, $value, $prefix);
    }
  }
}



