@use 'sass:list';
@use 'sass:map';
@use 'sass:math';
@use 'sass:meta';
@use '../contrast/luminance/luminance';

/// @deprecated Deprecated in version 0.87.0. Will be removed in version 0.90.0.
///
/// Take a numeric map and sort it.
///
/// https://gist.github.com/Jakobud/a0ac11e80a1de453cd86f0d3fc0a1410
/// Credit to: https://gist.github.com/iamandrewluca
///
@function _daff-illuminate-sort($map) {
	// Transform map to zipped list
	$keys: ();
	$values: ();

	@each $key, $val in $map {
		$keys: list.append($keys, $key);
		$values: list.append($values, $val);
	}

	$list: list.zip($keys, $values);

	$sorted-map: ();

	@while list.length($list) > 0 {
		// Find smallest pair
		$smallest-pair: list.nth($list, 1);

		@each $pair in $list {
			$value: list.nth($pair, 2);
			$smallest-value: list.nth($smallest-pair, 2);

			@if $value < $smallest-value {
				$smallest-pair: $pair;
			}
		}

		// Add smallest pair to sorted map
		$key: list.nth($smallest-pair, 1);
		$value: list.nth($smallest-pair, 2);
		$sorted-map: map.merge(
			$sorted-map,
			(
				$key: $value
			)
		);

		// Remove from list smallest pair
		$smallest-pair-index: list.index($list, $smallest-pair);
		$new-list: ();

		@for $i from 1 through list.length($list) {
			@if $i != $smallest-pair-index {
				$new-list: list.append($new-list, list.nth($list, $i), 'space');
			}
		}

		$list: $new-list;
	}

	@return $sorted-map;
}

// Given a map of key, luminance pairs, find the key
// of the value that is "nth" away from zero.
//
// @param $map: a map of key, luminance pairs,
// @param $nth: nth steps away from zero
@function _daff-illuminate-get-key($map, $nth: 1) {
	//Cap off "nth" to prevent going out-of-bounds.
	@if ($nth > list.length($map)) {
		$nth: list.length(map);
	}

	$map: _daff-illuminate-sort($map);
	@return list.nth(list.nth($map, $nth), 1);
}

// Takes a $color and palette and returns the color in
// the palette which would "illuminate" against that color.
//
// @usage
// ```
// daff-illuminate($palette);
// ```
//
@function daff-illuminate($color, $palette, $nth: 1) {
	$luminance-map: ();

	//Validate
	@each $key, $palette-color in $palette {
		@if (meta.type-of($key) == 'string') {
			$palette: map.remove($palette, $key);
		}
	}

	//Transform into usable values
	@each $key, $palette-color in $palette {
		$luminance-map: map.merge(
			$luminance-map,
			(
				$key: (
					luminance.daff-luminance($palette-color) - luminance.daff-luminance($color)
				)
			)
		);
	}


	//Calculate which color to get
	$brighter-colors: ();
	$darker-colors: ();

	@each $key, $luminance in $luminance-map {
		@if ($luminance > 0) {
			$brighter-colors: map.merge(
				$brighter-colors,
				(
					$key: $luminance
				)
			);
		}

		@if ($luminance < 0) {
			$darker-colors: map.merge(
				$darker-colors,
				(
					$key: math.abs($luminance)
				)
			);
		}
	}

	$key: null;

	@if (luminance.daff-luminance($color) >= 0.5) {
		//If the color is bright
		$key: _daff-illuminate-get-key($darker-colors, $nth);
	}
	@else {
		//If the color is dark
		$key: _daff-illuminate-get-key($brighter-colors, $nth);
	}

	@return map.get($palette, $key);
}
