@use 'sass:list';
@use 'sass:selector';
@use 'sass:string';
@use '../../functions/list/list-slice/list-slice.scss' as *;
@use '../../functions/string/str-trim/str-trim.scss' as *;
@use '../../variables' as vars;

/**
 * Allows to set a pseudo-element rules depending on its parent state
 * right in the rule set of the pseudo-element itself.
 *
 * @param    {list}    $states    Pseudo-element parent state(s) (pseudo-classes, modifier classes, etc.).
 */
@mixin parent-state($states...) {
	$selectors: selector.parse(&);

	$all-pseudo-elements: vars.$pseudo-elements;
	$compound-selector: ();

	@each $selector in $selectors {
		$selector: #{$selector};
		$pseudo: '';
		$_pseudo-elements: $all-pseudo-elements;

		@while (list.length($_pseudo-elements) > 0) {
			$pseudo-element: list.nth($_pseudo-elements, 1);
			$_pseudo-elements: list-slice($_pseudo-elements, 2);

			@if (string.slice($selector, string.length($pseudo-element) * -1) == $pseudo-element) {
				$pseudo: $pseudo-element;
				$selector: string.slice($selector, 1, string.length($pseudo) * -1 - 1);
				$_pseudo-elements: ();
			}
		}

		@if (str-trim($selector) != '') {
			@if (list.length($states) == 1) {
				$states: list.nth($states, 1);
			}

			$selector: selector.append($selector, $states);
			$selector: selector.append($selector, $pseudo);

			@each $part in $selector {
				$compound-selector: list.append($compound-selector, $part, comma);
			}
		}
	}

	@at-root #{$compound-selector} {
		@content;
	}
}
