// The functions in this file need to remain high-performance. Without care,
// these will create an unforgiving bottle-neck. Avoid unnecessary `map-set`
// calls and work with constants wherever possible.

// Generates a raw selector string.
@function _anthology-raw-selector($shorthand, $adjective, $breakpoint: null, $theme: null, $pseudo: null, $important: false)
{
  // Get shortcuts to config properties
  $sep: $_anthology-config-separator;
  $imp-tag: $_anthology-config-important-tag;
  $theme-tag: $_anthology-config-theme-tag;
  $res-tag: $_anthology-config-responsive-tag;

  // Build the resulting selector
  $result: '#{$shorthand}#{$sep}#{$adjective}';

  @if $important
  {
    $with-important: '#{$imp-tag}';
    $result: '#{$result}#{$sep}#{$with-important}';
  }

  @if $theme
  {
    $with-theme: '#{$theme-tag}#{$theme}';
    $result: '#{$result}#{$sep}#{$with-theme}';
  }

  @if $breakpoint
  {
    $with-breakpoint: '#{$res-tag}#{$breakpoint}';
    $result: '#{$result}#{$sep}#{$with-breakpoint}';
  }

  @if $pseudo
  {
    @if not A(str-starts-with, $pseudo, ':') and not A(str-starts-with, $pseudo, '::')
    {
      @error '[anthology::raw-selector] --- Expected a pseudo-class or pseudo-element, received `#{$pseudo}`.';
    }

    $with-pseudo: '\\\\#{$pseudo}';
    $result: '#{$result}#{$sep}#{$with-pseudo}';
  }

  @return $result;
}

// Generates a usable selector that targets themes and pseudo-elements/pseudo-classes.
@function _anthology-compound-selector($shorthand, $adjective, $silent, $breakpoint: null, $theme: null, $pseudo: null, $important: false)
{
  $theme-attr: $_anthology-config-theme-attr;

  // Build raw selector
  $theme-designation-selector: '[#{$theme-attr}~="#{$theme}"]';
  $raw-selector: _A(raw-selector,
    $shorthand: $shorthand,
    $adjective: $adjective,
    $breakpoint: $breakpoint,
    $theme: $theme,
    $pseudo: $pseudo,
    $important: $important,
  );

  $result: if(
    $silent,
    '%#{$raw-selector}',
    '.#{$raw-selector}',
  );

  @if $theme
  {
    @if $pseudo
    {
      $result: '#{$theme-designation-selector} #{$result}#{$pseudo}, #{$result}#{$theme-designation-selector}#{$pseudo}';
    }
    @else
    {
      $result: '#{$theme-designation-selector} #{$result}, #{$result}#{$theme-designation-selector}';
    }
  }
  @else if $pseudo
  {
    $result: '#{$result}#{$pseudo}';
  }

  $result: A(stringify, $result);

  @return $result;
}

// Generates all combinations of class attribute selectors for the given arguments.
@function _anthology-full-selector($shorthand, $adjective, $property, $value, $breakpoint, $pseudos, $themes, $important, $silent)
{
  $result: _A(compound-selector,
    $shorthand: $shorthand,
    $adjective: $adjective,
    $silent: $silent,
    $breakpoint: $breakpoint,
    $theme: null,
    $pseudo: null,
    $important: $important,
  );

  @if $pseudos
  {

    @each $pseudo in $pseudos
    {

      // pseudo + theme
      @if $themes
      {
        @each $theme in $themes
        {
          $selector: _A(compound-selector,
            $shorthand: $shorthand,
            $adjective: $adjective,
            $silent: $silent,
            $breakpoint: $breakpoint,
            $theme: $theme,
            $pseudo: $pseudo,
            $important: $important,
          );
          @if not A(str-contains, $result, $selector)
          {
            $result: '#{$result}, #{$selector}';
          }
        }
      }

      // pseudo only
      $selector: _A(compound-selector,
        $shorthand: $shorthand,
        $adjective: $adjective,
        $silent: $silent,
        $breakpoint: $breakpoint,
        $theme: null,
        $pseudo: $pseudo,
        $important: $important,
      );
      @if not A(str-contains, $result, $selector)
      {
        $result: '#{$result}, #{$selector}';
      }
    }
  }

  @if $themes
  {
    // theme only
    @each $theme in $themes
    {
      $selector: _A(compound-selector,
        $shorthand: $shorthand,
        $adjective: $adjective,
        $silent: $silent,
        $breakpoint: $breakpoint,
        $theme: $theme,
        $pseudo: null,
        $important: $important,
      );
      @if not A(str-contains, $result, $selector)
      {
        $result: '#{$result}, #{$selector}';
      }
    }
  }

  @return $result;
}
