////
/// (c) hidoo | MIT License
/// @group features
////

@use "sass:list";
@use "sass:map";
@use "sass:meta";
@use "sass:string";
@use "../../settings";
@use "../function";
@use "./media" as mixin;

/// Default options
/// @access private
/// @type Map
///
$_default-options: (
  "ignores": (),
  "target": ""
) !default;

/// Utility to generate selectors by breakpoints.
/// @param {Map} $breakpoints [()] - Breakpoints.
/// @param {Map} $options [()] - options
/// @param {List} $options.ignores [()] - Breakpoint names to ignore.
/// @param {String} $options.target [""] - Target selector string to replacement.
///
/// @example scss - scss inputs
///    $breakpoint: (
///      "sm": "(width <= 640px)",
///      "md": "(width <= 768px)",
///      ...
///    );
///
///   .selector {
///     @include mixin.by-breakpoints() {
///       font-size: 16px;
///     }
///   }
///
/// @example css - css outputs
///   .selector {
///     font-size: 16px;
///   }
///   @media (width <= 640px) {
///     .sm\:selector {
///       font-size: 16px;
///     }
///   }
///   @media (width <= 768px) {
///     .md\:selector {
///       font-size: 16px;
///     }
///   }
///   ...
///
@mixin by-breakpoints($breakpoints: null, $options: ()) {
  @if meta.type-of($breakpoints) != "map" {
    $breakpoints: settings.$breakpoints;
  }

  $opts: map.merge($_default-options, $options);
  $ignores: map.get($opts, "ignores");
  $target: map.get($opts, "target");

  @content;

  @each $bp, $query in $breakpoints {
    // Allows string queries only,
    // and ignores breakpoint start with `_` and specified by $options.ignores.
    @if meta.type-of($query) ==
      "string" and not
      (list.index($ignores, $bp) or string.index($bp, "_") == 1)
    {
      $selector: function.string-replace(
        "#{&}",
        ".#{$target}",
        ".#{$bp}\\:#{$target}"
      );

      @at-root {
        #{$selector} {
          @include mixin.media(
            $query: $bp,
            $options: (
              "breakpoints": $breakpoints
            )
          ) {
            @content;
          }
        }
      }
    }
  }
}
