// =============================================================================
// =ALEKSI - MAP-SORT-VALUES
// =============================================================================
////
//// @group aleksi-maps
//// @author [Yoannis Jamar](https://yoannis.com)

@import "aleksi/general/throw";
@import "aleksi/general/default-to";
@import "aleksi/lists/sort";
@import "aleksi/lists/whitout";
@import "aleksi/maps/is-map";

// =map-sort-values( $map[, $order ])
// -----------------------------------------------------------------------------
/// Orders a map's keys according to a given, ordered list of values. If no
/// order is specified, the alphabetic order of the map's values will be used.
/// **Note**: items with a value that is not in the ordered list will be added
/// at the end of the resulting map, in the same order as in the original map.
///
/// @param {map} $map - The map to sort
///
/// @return {type|...} - Description
/// @throw Error if `$map` is not a map
///
/// @access public
/// @since 0.1.0
///
/// @todo Manage duplicated values.

@function map-sort-values( $map, $order: null )
{
  @if not is-map($map) {
    @return throw-error('map-sort-keys():: $map must be a map, was #{inspect($map)}.');
  }

  $keys: map-keys($map);
  $values: map-values($map);
  $order: default-to($order, sort($values));
  $leftover: $keys;
  $res: ();

  @each $val in $order
  {
    $i: index($values, $val);
    @if $i
    {
      $key: nth($keys, $i);
      $res: map-merge( $res, ($key: $val));
      $leftover: list-without($leftover, $key);
    }
  }

  // include leftovers at the end
  @each $key in $leftover {
    $val: map-get($map, $key);
    $res: map-merge($res, ($key: $val));
  }

  @return $res;
}