////
/// @group selector
/// This module is used to alter selectors for components
////

@use "sass:string";
@use "sass:map";
@use "utils";

/// Module Settings
/// @type Map
/// @prop {String} prefix [""] Global prefix for selectors (would be used for classname prefix for example)

$config: (
  "prefix" : ""
) !default;

// Map to store class overrides ("button" : "site-button") for example
$-class-overrides: ();

// Map that stores wildcard entries
$-class-wildcards: ();

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss - General example
///   @include ulu.selector-set(( "property" : value ));
@mixin set($changes) {
  $config: map.merge($config, $changes) !global;
}

/// Get a config option
/// @param {Map} $name Name of property
/// @example scss - General example
///   @include ulu.selector-get("property");

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

/// Set the class selector overrides
/// - When a component or user module that is using selector module requests a classname any changes passed here will override the default selector
/// @param {Map} $changes Changes to merge map of classnames to classname change
/// @example scss - Changing the color-context classname to background and all typography base/utility classes to 'text' using wildcard
///   @include ulu.selector-set-class-overrides((
///     "color-context" : "background",
///     "type*" : "text"
///   ));

@mixin set-class-overrides($changes) {
  @each $key, $prop in $changes {
    $index: string.index($key, "*");
    @if ($index) {
      $wild-key: string.slice($key, 1, $index - 1);
      $-class-wildcards: map.set($-class-wildcards, $wild-key, $prop) !global;
      $changes: map.remove($changes, $key);
    }
  }
  $-class-overrides: map.merge($-class-overrides, $changes) !global;
}

/// Used to allow global prefixing of classes, and also the ability to 
/// Change a class used in the system (ie. like a component for example)
/// @param {String} $class The base classname to get (which is then returned modified if the user has adjusted that specific classname

@function class($class, $name-only: false) {
  // Check if it's a wildcard
  $wildcard: -get-class-wildcard($class);
  $override: map.get($-class-overrides, $class);
  $updated: if($override, $override, if($wildcard, $wildcard, $class));
  $name: "#{ get("prefix") }#{ $updated }";
  @if $name-only {
    @return $name;
  } @else {
    @return ".#{ $name }";
  }
}

// Internal function to check all wildcards entries for passed class

@function -get-class-wildcard($class) {
  $change: $class;
  @each $key, $prop in $-class-wildcards {
    $index: string.index($class, $key);
    @if ($index) {
      $change: utils.string-replace($class, $key, $prop);
    }
  }
  @return $change;
}