////
/// @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') {
		$properties: (
			'-moz-appearance',
			'-moz-osx-font-smoothing',
			'-ms-overflow-style',
			'-webkit-appearance',
			'-webkit-font-smoothing',
			'-webkit-overflow-scrolling',
			'-webkit-tap-highlight-color',
			'-webkit-text-size-adjust',
			'accent-color',
			'align-content',
			'align-items',
			'align-self',
			'animation',
			'animation-delay',
			'animation-direction',
			'animation-duration',
			'animation-fill-mode',
			'animation-iteration-count',
			'animation-name',
			'animation-play-state',
			'animation-timing-function',
			'aspect-ratio',
			'backdrop-filter',
			'backface-visibility',
			'background',
			'background-attachment',
			'background-blend-mode',
			'background-clip',
			'background-color',
			'background-image',
			'background-origin',
			'background-position',
			'background-repeat',
			'background-size',
			'border',
			'border-bottom',
			'border-bottom-color',
			'border-bottom-left-radius',
			'border-bottom-right-radius',
			'border-bottom-style',
			'border-bottom-width',
			'border-collapse',
			'border-color',
			'border-image',
			'border-image-outset',
			'border-image-repeat',
			'border-image-slice',
			'border-image-source',
			'border-image-width',
			'border-left',
			'border-left-color',
			'border-left-style',
			'border-left-width',
			'border-radius',
			'border-right',
			'border-right-color',
			'border-right-style',
			'border-right-width',
			'border-spacing',
			'border-style',
			'border-top',
			'border-top-color',
			'border-top-left-radius',
			'border-top-right-radius',
			'border-top-style',
			'border-top-width',
			'border-width',
			'bottom',
			'box-decoration-break',
			'box-shadow',
			'box-sizing',
			'caption-side',
			'caret-color',
			'clear',
			'clip',
			'-webkit-clip-path',
			'clip-path',
			'contain',
			'container',
			'container-name',
			'container-type',
			'color',
			'column-count',
			'column-fill',
			'column-gap',
			'column-rule',
			'column-rule-color',
			'column-rule-style',
			'column-rule-width',
			'column-span',
			'column-width',
			'columns',
			'content',
			'counter-increment',
			'counter-reset',
			'cursor',
			'direction',
			'display',
			'empty-cells',
			'fill',
			'filter',
			'flex',
			'flex-basis',
			'flex-direction',
			'flex-flow',
			'flex-grow',
			'flex-shrink',
			'flex-wrap',
			'float',
			'font',
			'font-family',
			'font-feature-settings',
			'font-kerning',
			'font-size',
			'font-stretch',
			'font-style',
			'font-variant',
			'font-variant-numeric',
			'font-weight',
			'gap',
			'grid',
			'grid-area',
			'grid-auto-columns',
			'grid-auto-flow',
			'grid-auto-rows',
			'grid-column',
			'grid-column-end',
			'grid-column-gap',
			'grid-column-start',
			'grid-gap',
			'grid-row',
			'grid-row-end',
			'grid-row-gap',
			'grid-row-start',
			'grid-template',
			'grid-template-areas',
			'grid-template-columns',
			'grid-template-rows',
			'height',
			'hyphens',
			'inset',
			'isolation',
			'justify-content',
			'left',
			'letter-spacing',
			'line-height',
			'list-style',
			'list-style-image',
			'list-style-position',
			'list-style-type',
			'margin',
			'margin-bottom',
			'margin-left',
			'margin-right',
			'margin-top',
			'-webkit-mask',
			'-webkit-mask-clip',
			'-webkit-mask-composite',
			'-webkit-mask-image',
			'-webkit-mask-mode',
			'-webkit-mask-origin',
			'-webkit-mask-position',
			'-webkit-mask-repeat',
			'-webkit-mask-size',
			'mask',
			'mask-clip',
			'mask-composite',
			'mask-image',
			'mask-mode',
			'mask-origin',
			'mask-position',
			'mask-repeat',
			'mask-size',
			'max-height',
			'max-width',
			'min-height',
			'min-width',
			'mix-blend-mode',
			'object-fit',
			'object-position',
			'opacity',
			'order',
			'outline',
			'outline-color',
			'outline-offset',
			'outline-style',
			'outline-width',
			'overflow',
			'overflow-x',
			'overflow-y',
			'overscroll-behavior',
			'overscroll-behavior-x',
			'overscroll-behavior-y',
			'padding',
			'padding-bottom',
			'padding-left',
			'padding-right',
			'padding-top',
			'page-break-after',
			'page-break-before',
			'page-break-inside',
			'perspective',
			'perspective-origin',
			'place-content',
			'place-items',
			'place-self',
			'pointer-events',
			'position',
			'resize',
			'right',
			'row-gap',
			'scroll-behavior',
			'scroll-margin',
			'scroll-margin-bottom',
			'scroll-margin-left',
			'scroll-margin-right',
			'scroll-margin-top',
			'scroll-padding',
			'scroll-padding-bottom',
			'scroll-padding-left',
			'scroll-padding-right',
			'scroll-padding-top',
			'scroll-snap-align',
			'scroll-snap-stop',
			'scroll-snap-type',
			'scrollbar-width',
			'table-layout',
			'text-align',
			'text-decoration',
			'text-decoration-color',
			'text-decoration-line',
			'text-decoration-skip-ink',
			'text-decoration-style',
			'text-decoration-thickness',
			'text-underline-offset',
			'text-underline-position',
			'text-indent',
			'text-justify',
			'text-overflow',
			'text-shadow',
			'text-transform',
			'top',
			'touch-action',
			'transform',
			'transform-origin',
			'transform-style',
			'transition',
			'transition-delay',
			'transition-duration',
			'transition-property',
			'transition-timing-function',
			'vertical-align',
			'visibility',
			'white-space',
			'width',
			'will-change',
			'word-break',
			'word-spacing',
			'writing-mode',
			'z-index'
		);

		$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 {
				@if ($value == clay-unset or $value == c-unset) {
					$value: null;
				}

				@if (starts-with($key, '--')) {
					#{$key}: $value;
				}

				@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 if (index($properties, $key)) {
					#{$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);
					}
				}
			}
		}
	}
}
