////
/// @group globals
////

/// A mixin that outputs a CSS property based on the `key: value` pair passed to
/// the mixin. Outputs nothing if no `key: value` pairs are passed. Prevent a
/// Clay CSS Sass map from outputting properties with
/// `$the-variable: (enabled: false);`
/// @param {Map} $map - A map of `key: value` pairs.

@mixin clay-css($map) {
	@if (type-of($map) == 'map') {
		$enabled: setter(map-get($map, enabled), true);

		$_prefers-reduced-motion-media-query: if(
			variable-exists(enable-prefers-reduced-motion-media-query),
			$enable-prefers-reduced-motion-media-query,
			if(
				variable-exists(
					cadmin-enable-prefers-reduced-motion-media-query
				),
				$cadmin-enable-prefers-reduced-motion-media-query,
				true
			)
		);

		@if ($enabled) {
			@each $key, $value in $map {
				// $variable: (); defaults to type `list`, convert empty maps
				// to type map

				@if (length($value) == 0 and type-of($value) == 'list') {
					$value: map-new();
				}

				@if (type-of($value) != 'map') {
					@if ($key != 'enabled') {
						@if ($value == clay-unset or $value == c-unset) {
							$value: null;
						} @else if ($key == 'appearance') {
							-moz-appearance: $value;
							-webkit-appearance: $value;

							&::-ms-expand {
								display: $value;
							}

							appearance: $value;
						} @else if ($key == 'animation') {
							animation: $value;

							@if ($value != 'none' and $value != null) {
								@if ($_prefers-reduced-motion-media-query) {
									@media (prefers-reduced-motion: reduce) {
										animation: none;
									}
								}

								@at-root {
									$selector: '.c-prefers-reduced-motion &';

									@if (variable-exists(cadmin-selector)) {
										$selector: clay-insert-before(
											'.cadmin',
											'.c-prefers-reduced-motion '
										);
									}

									#{$selector} {
										animation: none;
									}
								}
							}
						} @else if ($key == 'content') {
							content: $value;
						} @else if ($key == 'word-wrap') {
							overflow-wrap: $value;
							word-wrap: $value;
						} @else if ($key == 'overflow-wrap') {
							overflow-wrap: $value;
							word-wrap: $value;
						} @else if ($key == 'text-overflow') {
							@if ($value == 'ellipsis') {
								text-overflow: $value;

								@at-root {
									$selector: '.c-prefers-expanded-text &';

									@if (variable-exists(cadmin-selector)) {
										$selector: clay-insert-before(
											'.cadmin',
											'.c-prefers-expanded-text '
										);
									}

									#{$selector} {
										@extend %c-prefers-expanded-text
												!optional;
									}
								}
							}
						} @else if ($key == 'transition') {
							transition: $value;

							@if ($value != 'none' and $value != null) {
								@if ($_prefers-reduced-motion-media-query) {
									@media (prefers-reduced-motion: reduce) {
										transition: none;
									}
								}

								@at-root {
									$selector: '.c-prefers-reduced-motion &';

									@if (variable-exists(cadmin-selector)) {
										$selector: clay-insert-before(
											'.cadmin',
											'.c-prefers-reduced-motion '
										);
									}

									#{$selector} {
										transition: none;
									}
								}
							}
						} @else if ($key == 'extend') {
							@extend #{$value} !optional;
						} @else if ($key == 'user-select') {
							-ms-user-select: $value;
							-moz-user-select: $value;
							-webkit-user-select: $value;
							user-select: $value;
						} @else if ($key == 'aspect-ratio') {
							@if (type-of($value) != 'map') {
								aspect-ratio: $value;
							}
						} @else {
							#{$key}: #{$value};
						}
					}
				}
			}

			$_media-breakpoint-down: map-get($map, media-breakpoint-down);
			$_media-breakpoint-up: map-get($map, media-breakpoint-up);

			@if ($_media-breakpoint-down) or ($_media-breakpoint-up) {
				@include clay-generate-media-breakpoints($map);
			}
		}
	}
}

/// A mixin that outputs CSS based on the structure of a Sass map.
/// @param {Map} $map - A map of `key: value` pairs.

@mixin clay-map-to-css($map) {
	@include clay-css($map);

	@each $key, $value in $map {
		@if not clay-is-map-unset($value) {
			@if (type-of($value) == 'map') {
				$pseudo-classes: 'active', 'disabled', 'first-child', 'focus',
					'hover', 'last-child', 'visited';

				$pseudo-elements: 'after', 'before';

				$valid-prefixes: '#', '&', '.', '>', '@', '~', '+', '[';

				@if (index($pseudo-classes, $key)) {
					$key: str-insert($key, '&:', 1);
				}

				@if (index($pseudo-elements, $key)) {
					$key: str-insert($key, '&::', 1);
				}

				$selector: if(
					index($valid-prefixes, str-slice($key, 1, 1)),
					$key,
					str-insert($key, '.', 1)
				);

				@if (starts-with($selector, '@media ')) {
					@media #{clay-str-replace('#{$selector}', '@media ', '')} {
						@include clay-map-to-css($value);
					}
				} @else if (starts-with($selector, '@container ')) {
					@at-root {
						@container #{clay-str-replace('#{$selector}', '@container ', '')} {
							& {
								@include clay-map-to-css($value);
							}
						}
					}
				} @else if (starts-with($selector, '@supports ')) {
					@supports #{clay-str-replace(
							'#{$selector}',
							'@supports ',
							''
						)} {
						@include clay-map-to-css($value);
					}
				} @else {
					#{$selector} {
						@include clay-map-to-css($value);
					}
				}
			}
		}
	}
}
