// -----------------------------------------------------------------------------
// Quantity queries
// -----------------------------------------------------------------------------
// Table of contents:
// 1. Last Simple Selector
// 2. Build Quantity Selector
// 3. At least
// 4. At most
// 5. Between
// 6. Exactly


// -----------------------------------------------------------------------------
// 1. Last Simple Selector
// -----------------------------------------------------------------------------

/// Find the last simple selector in a given selector
/// @access private
/// @param  {list | string} $selector - A single selector
/// @return {string}                  - The last simple selector in $selector
/// @example scss
///   $result: _last-simple-selector(ul > li); // li

@function _last-simple-selector($selector) {
    $parsed: selector-parse($selector);

    @if length($parsed) > 1 {
      @error '`#{$selector}` contains #{length($parsed)} selectors and the `_last-simple-selector()`function accepts only 1.';
    }
    $last-simple-selector: nth(nth($parsed, 1), -1);

    @return $last-simple-selector;
}


// -----------------------------------------------------------------------------
// 2. Build Quantity Selector
// -----------------------------------------------------------------------------

/// Builds the selector for the quantity query
/// @access private
/// @param  {string} $selector-append      - The selector to be appended
/// @param  {string} $last-selector        - The item's selector
/// @return {list}                         - The final quantity query selector

@function _build-quantity-selector($selector-append, $last-selector) {
    $quantity-selector: ();

    @each $s in & {
        $last-simple-selector: '~' + if($last-selector, $last-selector, _last-simple-selector($s));
        $sel: selector-append($s, $selector-append);
        $sel2: selector-nest($sel, $last-simple-selector);
        $quantity-selector: append($quantity-selector, $sel, 'comma');
        $quantity-selector: append($quantity-selector, $sel2 , 'comma');
    }

    @return $quantity-selector;
}


// -----------------------------------------------------------------------------
// 3. At least
// -----------------------------------------------------------------------------

/// Query when total items is at least N items
/// @param  {number} $count - Quantity to match (equal or more)
/// @example scss - Make the items color red when there are 4 items or more
///   ul li {
///     @include at-least(4) { color: red; }
///   }
/// @example scss - Make the items color blue when there are 6 items or more and use '*' (element agnostic) as the item selector
///   ul li {
///     @include at-least(6, '*') { color: blue; }
///   }

@mixin at-least($count, $selector: null) {
    $selector-append: ':nth-last-child(n+#{$count})';

    @if type-of($count) != 'number' or not unitless($count) or $count < 1 {
        @error '`#{$count}` is not a valid number for `at-least`';
    }

    @if $selector != null and (type-of($selector) != 'string' or length($selector) > 1) {
        @error '`#{$selector}` is not a valid selector for `at-least`';
    }

    $at-least-selector: _build-quantity-selector($selector-append, $selector);


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


// -----------------------------------------------------------------------------
// 4. At most
// -----------------------------------------------------------------------------

/// Query when total items is at most N items
/// @param  {number} $count - Quantity to match (equal or less)
/// @example scss - Make the items color red when there are 4 items or less
///   ul li {
///     @include at-most(4) { color: red; }
///   }
/// @example scss - Make the items color blue when there are 6 items or less and use '*' (element agnostic) as the item selector
///   ul li {
///     @include at-most(6, '*') { color: blue; }
///   }

@mixin at-most($count, $selector: null) {
    $selector-append: ':nth-last-child(-n+#{$count}):first-child';

    @if type-of($count) != 'number' or not unitless($count) or $count < 1 {
        @error '`#{$count}` is not a valid number for `at-most`.';
    }

    @if $selector != null and (type-of($selector) != 'string' or length($selector) > 1) {
        @error '`#{$selector}` is not a valid selector for `at-most`';
    }

    $at-most-selector: _build-quantity-selector($selector-append, $selector);


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


// -----------------------------------------------------------------------------
// 5. Between
// -----------------------------------------------------------------------------

/// Query when total items is at least X items and at most Y items
/// @param  {number} $at-least - Lower quantity of items to match
/// @param  {number} $at-most - Higher quantity of items to match
/// @example scss - Make the items color red when there are at least 2 and at most 4 items
///   ul li {
///     @include between(4, 8) { color: red; }
///   }
/// @example scss - Make the items color blue when there are at least 6 items and at most 10 items and use '*' (element agnostic) as the item selector
///   ul li {
///     @include between(6, 10, '*') { color: blue; }
///   }


@mixin between($first, $last, $selector: null) {
    $selector-append: ':nth-last-child(n+#{$first}):nth-last-child(-n+#{$last}):first-child';

    @if type-of($first) != 'number' or not unitless($first) or $first < 1 {
        @error '`#{$first}` is not a valid number for `between`';
    }

    @if type-of($last) != 'number' or not unitless($last) or $last < 1 {
        @error '`#{$last}` is not a valid number for `between`';
    }

    @if $first > $last {
        @error '#{$first} can´t be larger that #{$last} for `between`';
    }

    @if $selector != null and (type-of($selector) != 'string' or length($selector) > 1) {
        @error '`#{$selector}` is not a valid selector for `between`';
    }

    $between-selector: _build-quantity-selector($selector-append, $selector);


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


// -----------------------------------------------------------------------------
// 6. Exactly
// -----------------------------------------------------------------------------

/// Query when total items is exactly N items
/// @param  {number} $count - Quantity to match (equal)
/// @example scss - Make the items color red when there are exactly 4 items
///   ul li {
///     @include exactly(4) { color: red; }
///   }
/// @example scss - Make the items color blue when there are exactly 6 items and use '*' (element agnostic) as the item selector
///   ul li {
///     @include exactly(6, '*') { color: blue; }
///   }

@mixin exactly($count, $selector: null) {
    $selector-append: ':nth-last-child(#{$count}):first-child';

    @if type-of($count) != 'number' or not unitless($count) or $count < 1 {
        @error '`#{$count}` is not a valid number for `exactly`';
    }

    @if $selector != null and (type-of($selector) != 'string' or length($selector) > 1) {
        @error '`#{$selector}` is not a valid selector for `exactly`';
    }

    $exactly-selector: _build-quantity-selector($selector-append, $selector);


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