@use 'sass:map';
@use 'sass:meta';
@use 'function';
@use '../common/var';
@use 'config';

// Module-level variables for BEM mixins
$B: null;
$E: null;

/* Break-points
 -------------------------- */
@mixin res($key, $map: var.$breakpoints) {
	// 循环断点Map，如果存在则返回
	@if map.has-key($map, $key) {
		@media only screen and #{meta.inspect(map.get($map, $key))} {
			@content;
		}
	} @else {
		@warn "Undefeined points: `#{$map}`";
	}
}

/* Scrollbar
 -------------------------- */
@mixin scroll-bar {
	scrollbar-width: thin;
	scrollbar-color: var.$scrollbar-background-color transparent;

	&::-webkit-scrollbar {
		z-index: 11;
		width: 6px;

		&:horizontal {
			height: 6px;
		}

		&-thumb {
			border-radius: 5px;
			width: 6px;
			background-color: var.$scrollbar-background-color;

			&:hover {
				background-color: var.$scrollbar-hover-background-color;
			}
		}

		&-corner,
		&-track,
		&-track-piece {
			background-color: transparent;
		}
	}
}

@mixin hoverable-scroll-bar {
	@include scroll-bar;
	scrollbar-color: transparent transparent;

	&::-webkit-scrollbar-thumb {
		background-color: transparent;
	}

	&:hover {
		scrollbar-color: var.$scrollbar-background-color transparent;

		&::-webkit-scrollbar-thumb {
			background-color: var.$scrollbar-background-color;

			&:hover {
				background-color: var.$scrollbar-hover-background-color;
			}
		}
	}
}

@mixin scroll-mask($edge, $size: var(--spacing--sm)) {
	@if $edge == top {
		mask-image: linear-gradient(to bottom, transparent 0, black $size, black 100%);
	} @else if $edge == bottom {
		mask-image: linear-gradient(to bottom, black 0, black calc(100% - $size), transparent 100%);
	} @else if $edge == left {
		mask-image: linear-gradient(to right, transparent 0, black $size, black 100%);
	} @else if $edge == right {
		mask-image: linear-gradient(to right, black 0, black calc(100% - $size), transparent 100%);
	} @else if $edge == y {
		mask-image: linear-gradient(
			to bottom,
			transparent 0,
			black $size,
			black calc(100% - $size),
			transparent 100%
		);
	} @else if $edge == x {
		mask-image: linear-gradient(
			to right,
			transparent 0,
			black $size,
			black calc(100% - $size),
			transparent 100%
		);
	} @else {
		@error "Unsupported scroll mask edge: #{$edge}";
	}
}

/* Placeholder
 -------------------------- */
@mixin placeholder {
	&::-webkit-input-placeholder {
		@content;
	}

	&::-moz-placeholder {
		@content;
	}

	&:-ms-input-placeholder {
		@content;
	}
}

/* BEM
 -------------------------- */
@mixin b($block) {
	$B: config.$namespace + '-' + $block !global;

	.#{$B} {
		@content;
	}
}

@mixin e($element) {
	$E: $element !global;
	$selector: &;
	$currentSelector: '';
	@each $unit in $element {
		$currentSelector: #{$currentSelector + '.' + $B + config.$element-separator + $unit + ','};
	}

	@if function.hitAllSpecialNestRule($selector) {
		@at-root {
			#{$selector} {
				#{$currentSelector} {
					@content;
				}
			}
		}
	} @else {
		@at-root {
			#{$currentSelector} {
				@content;
			}
		}
	}
}

@mixin m($modifier) {
	$selector: &;
	$currentSelector: '';
	@each $unit in $modifier {
		$currentSelector: #{$currentSelector + & + config.$modifier-separator + $unit + ','};
	}

	@at-root {
		#{$currentSelector} {
			@content;
		}
	}
}

@mixin configurable-m($modifier, $E-flag: false) {
	$selector: &;
	$interpolation: '';

	@if $E-flag {
		$interpolation: config.$element-separator + $E-flag;
	}

	@at-root {
		#{$selector} {
			.#{$B + $interpolation + config.$modifier-separator + $modifier} {
				@content;
			}
		}
	}
}

@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) {
	$modifierCombo: '';

	@if $modifier {
		$modifierCombo: config.$modifier-separator + $modifier;
	}

	@at-root {
		#{&}#{$specSelector}.#{$block + config.$element-separator + $element + $modifierCombo} {
			@content;
		}
	}
}

@mixin meb($modifier: false, $element: $E, $block: $B) {
	$selector: &;
	$modifierCombo: '';

	@if $modifier {
		$modifierCombo: config.$modifier-separator + $modifier;
	}

	@at-root {
		#{$selector} {
			.#{$block + config.$element-separator + $element + $modifierCombo} {
				@content;
			}
		}
	}
}

@mixin when($state) {
	@at-root {
		&.#{config.$state-prefix + $state} {
			@content;
		}
	}
}

@mixin extend-rule($name) {
	@extend #{'%shared-' + $name};
}

@mixin share-rule($name) {
	$rule-name: '%shared-' + $name;

	@at-root #{$rule-name} {
		@content;
	}
}

@mixin pseudo($pseudo) {
	@at-root #{&}#{':#{$pseudo}'} {
		@content;
	}
}
