/**
 * ui-button core component
 *  Custom properties and styles with configuration
 */

/**
 * Requires
 */
@use 'sass:map';
@use 'sass:meta';
@use '../abstract';
@use '../mixins';
@use '../media';

/**
 * Component css class
 * @protected
 * @type {string} css class
 */
$class: 'ui-button' !default;

/**
 * Component property prefix
 * @protected
 * @type {string} property name
 */
$props: 'ui-button-' !default;

/**
 * Config defaults
 * @private
 * @type {map}
 */
$-config: (
  margin: auto 0,
  margin-inline: 0.25em,
  padding: 0.25em,
  icon-padding: 0.25em,
  border: 1px solid currentColor,
  border-radius: 0.25em,
  icon-spacing: 0.25em,
  label-spacing: 0.25em,
  min-width: 8em,
  max-width: min(24em, 100%),
  disabled-opacity: 0.6,
  transition: 0.3s ease,
  label-hidden-queries: null,
);

/**
 * Update component config options
 * @public
 * @param {map} $options - Map of config options
 * @output {void} - Only sets config options
 */
@mixin config($options) {
  $-config: abstract.config($options, $-config, true, true, 'button-core.config::') !global;
}

/**
 * Generate required custom properties
 * @public
 * @param {null|map} $extend - Extend properties for output only
 * @output Adds components custom properties in current scope
 */
@mixin properties($extend: null) {
  $render: abstract.merge-optional($-config, $extend);
  $clean: map.remove($render, 'label-hidden-queries');
  @include mixins.properties($clean, $props, '_at_', 'button-core.properties::');
}

/**
 * Generate button core styles
 * @public
 * @output Outputs configured button base styles in given context
 */
@mixin styles() {
  .#{$class} {
    cursor: pointer;
    position: relative;
    display: inline-block;
    margin: var(--#{$props}margin);
    margin-inline: var(--#{$props}margin-inline);
    padding: var(--#{$props}padding);
    border: var(--#{$props}border);
    border-radius: var(--#{$props}border-radius);
    vertical-align: middle;
    opacity: 1;
    transition: var(--#{$props}transition);

    // Should have a consistent line-height or sizing might get out of hand
    // line-height: inherit;

    &:first-child {
      margin-left: 0;
      margin-inline-start: 0;
    }
    &:last-child {
      margin-right: 0;
      margin-inline-end: 0;
    }

    &__label {
      display: inline-block;
      @include mixins.no-select;
    }

    &:disabled,
    &--disabled {

      // Could require a pointer-events: none;
      // to be set which negates the mouse cursor.
      cursor: not-allowed;
      opacity: var(--#{$props}disabled-opacity);
    }

    &--icon {
      --#{$props}padding: var(--#{$props}icon-padding);
      display: inline-flex;
      align-items: center;

      .#{$class}__label:last-child:not(:first-child) {
        margin-left: var(--#{$props}icon-spacing);
        margin-right: var(--#{$props}label-spacing);
      }
      .#{$class}__label:first-child:not(:last-child) {
        margin-left: var(--#{$props}label-spacing);
        margin-right: var(--#{$props}icon-spacing);
      }

      &-only {
        .#{$class}__label {
          @include mixins.hide-accessible;
        }
      }
    }

    &--label-hidden {
      .#{$class}__label {
        @include mixins.hide-accessible;
      }

      // Query based hidden label
      $-label-hidden-queries: map.get($-config, 'label-hidden-queries');
      @debug($-label-hidden-queries);
      @if meta.type-of($-label-hidden-queries) == list {
        @each $query in $-label-hidden-queries {
          @include media.query($query) {
            &-#{abstract.str-initials($query)} {
              .#{$class}__label {
                @include mixins.hide-accessible;
              }
            }
          }
        }
      }
    }

    &--center {
      justify-content: center;
      text-align: center;
    }

    &--min-width {
      min-width: var(--#{$props}min-width);
    }

    &--max-width {
      max-width: var(--#{$props}max-width);
    }

    &--wide {
      width: 100%;
    }

    // Looks like a button, but isn't a button
    &--static {
      cursor: default;
    }

    // Allow additional styles
    @if meta.content-exists() {
      @content;
    }
  }
}
