/// Easily grab a color from a map.
///
/// @group 02-color
///
/// @param {Map} $map - The map containing the color value.
/// @param {Number|String} $key - The key for the desired value.
/// @return {Color} - The desired color.
@function color($map, $key) {
  @if not $map {
    @error '`#{inspect($map)}` map not found!';
  }

  @if not map-get($map, $key) {
    @error 'No key `#{inspect($key)}` found in `#{$map}`!';
  }

  @return map-get($map, $key);
}

/// Get a primary color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$primary-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function primary-color($key, $map: $primary-colors) {
  @return color($map, $key);
}

/// Get a neutral color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$neutral-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function neutral-color($key, $map: $neutral-colors) {
  @return color($map, $key);
}

/// Get a accent color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$accent-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function neutral-color($key, $map: $accent-colors) {
  @return color($map, $key);
}

/// Get a success color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$success-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function success-color($key, $map: $success-colors) {
  @return color($map, $key);
}

/// Get a warning color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$warning-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function warning-color($key, $map: $warning-colors) {
  @return color($map, $key);
}

/// Get a danger color value.
///
/// @group 02-color
///
/// @param {Number|String} $key - The key for the desired value.
/// @param {Map} $map [$danger-colors] - The map containing the color value.
/// @return {Color} - The desired color.
@function danger-color($key, $map: $danger-colors) {
  @return color($map, $key);
}

/// Tint a color (add white) by a specified amount.
///
/// @group 02-color
///
/// @param  {Color}  $color  - The color to tint.
/// @param  {Number} $amount - The amount of white to add.
/// @return {Color}          - The tinted color.
@function tint($color, $amount) {
  @return mix(#fff, $color, $amount);
}

/// Tone a color (add gray) by a specified amount.
///
/// @group 02-color
///
/// @param  {Color}  $color          - The color to tone.
/// @param  {Number} $amount         - The amount of gray to add.
/// @param  {Color}  $gray [#808080] - The gray to mix.
/// @return {Color}                  - The toned color.
@function tone($color, $amount, $gray: neutral-color(500)) {
  @return mix($gray, $color, $amount);
}

/// Shade a color (add black) by a specified amount.
///
/// @group 02-color
///
/// @param  {Color}  $color  - The color to shade.
/// @param  {Number} $amount - The amount of black to add.
/// @return {Color}          - The shaded color.
@function shade($color, $amount) {
  @return mix(#000, $color, $amount);
}

/// Calculate the luminance of a given color.
///
/// @group 02-color
///
/// @param  {Color}  $color - The color to check.
/// @return {Number}        - The color's luminance.
///
/// @link   https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
@function luminance($color) {
  $red: red($color) * 0.2126;
  $green: green($color) * 0.7152;
  $blue: blue($color) * 0.0722;

  @return $red + $green + $blue;
}

/// Calculate the contrast between two colors.
///
/// @group 02-color
///
/// @param  {Color}  $color1 - The first color to check.
/// @param  {Color}  $color2 - The second color to check.
/// @return {Number}         - The contrast ratio between the two colors.
///
/// @link   https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
@function calculate-contrast($color1, $color2) {
  $color1: luminance($color1) + 0.05;
  $color2: luminance($color2) + 0.05;

  @return max($color1, $color2) / min($color1, $color2);
}

/// Chooses the color with the best contrast for the base.
///
/// @group 02-color
///
/// @param  {Color} $base-color                  - The color against which to check.
/// @param  {Color} $light [$text-default-light] - The light color against which to check.
/// @param  {Color} $dark  [$text-default-dark]  - The dark color against which to check.
/// @return {Color}                              - The color with the better contrast.
///
/// @link   https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
@function contrast($base-color, $light: $text-default-light, $dark: $text-default-dark) {
  $contrast-light: calculate-contrast($base-color, $light);
  $contrast-dark: calculate-contrast($base-color, $dark);

  @if ($contrast-light > $contrast-dark) {
    @return $light;
  } @else {
    @return $dark;
  }
}
