@use 'sass:math';
@use '@angular/cdk';
@use '../core/style/vendor-prefixes';
@use '../core/style/variables';
@use '../core/tokens/token-utils';
@use '../core/tokens/m2/mat/select' as tokens-mat-select;

$mat-select-arrow-size: 5px !default;
$mat-select-arrow-margin: 4px !default;
$mat-select-panel-max-height: 275px !default;
$mat-select-placeholder-arrow-space: 2 *
  ($mat-select-arrow-size + $mat-select-arrow-margin);
$leading-width: 12px !default;
$scale: 0.75 !default;


.mat-mdc-select {
  display: inline-block;
  width: 100%;
  outline: none;

  @include token-utils.use-tokens(
    tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include vendor-prefixes.smooth-font();
    @include token-utils.create-token-slot(color, enabled-trigger-text-color);
    @include token-utils.create-token-slot(font-family, trigger-text-font);
    @include token-utils.create-token-slot(line-height, trigger-text-line-height);
    @include token-utils.create-token-slot(font-size, trigger-text-size);
    @include token-utils.create-token-slot(font-weight, trigger-text-weight);
    @include token-utils.create-token-slot(letter-spacing, trigger-text-tracking);
  }
}
@include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
  div.mat-mdc-select-panel {
    @include token-utils.create-token-slot(box-shadow, container-elevation-shadow);
  }
}

.mat-mdc-select-disabled {
  @include token-utils.use-tokens(
    tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include token-utils.create-token-slot(color, disabled-trigger-text-color);
  }
}

.mat-mdc-select-trigger {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  position: relative;
  box-sizing: border-box;
  width: 100%;

  .mat-mdc-select-disabled & {
    @include vendor-prefixes.user-select(none);
    cursor: default;
  }
}

.mat-mdc-select-value {
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mat-mdc-select-value-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mat-mdc-select-arrow-wrapper {
  height: 24px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;

  .mat-form-field-appearance-fill .mdc-text-field--no-label & {
    transform: none;
  }
}

.mat-mdc-form-field .mat-mdc-select.mat-mdc-select-invalid .mat-mdc-select-arrow,
.mat-form-field-invalid:not(.mat-form-field-disabled) .mat-mdc-form-field-infix::after {
  @include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include token-utils.create-token-slot(color, invalid-arrow-color);
  }
}

.mat-mdc-select-arrow {
  width: $mat-select-arrow-size * 2;
  height: $mat-select-arrow-size;
  position: relative;

  @include token-utils.use-tokens(
    tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include token-utils.create-token-slot(color, enabled-arrow-color);

    .mat-mdc-form-field.mat-focused & {
      @include token-utils.create-token-slot(color, focused-arrow-color);
    }

    .mat-mdc-form-field .mat-mdc-select.mat-mdc-select-disabled & {
      @include token-utils.create-token-slot(color, disabled-arrow-color);
    }
  }

  svg {
    fill: currentColor;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    @include cdk.high-contrast {
      // On Chromium browsers the `currentColor` blends in with the
      // background for SVGs so we have to fall back to `CanvasText`.
      fill: CanvasText;

      .mat-mdc-select-disabled & {
        fill: GrayText;
      }
    }
  }
}

// Even though we don't use the MDC styles, we need to keep the classes in the
// DOM for the Gmat versions to work. We need to bump up the specificity here
// so that it's higher than MDC's styles.
div.mat-mdc-select-panel {
  width: 100%; // Ensures that the panel matches the overlay width.
  max-height: $mat-select-panel-max-height;
  outline: 0;
  overflow: auto;
  padding: 8px 0;
  border-radius: 4px;
  box-sizing: border-box;

  // Workaround in case other MDC menu surface styles bleed in.
  position: static;

  @include token-utils.use-tokens(
    tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include token-utils.create-token-slot(background-color, panel-background-color);
  }

  @include cdk.high-contrast {
    outline: solid 1px;
  }

  .cdk-overlay-pane:not(.mat-mdc-select-panel-above) & {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
    transform-origin: top center;
  }

  .mat-mdc-select-panel-above & {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    transform-origin: bottom center;
  }

  .mat-mdc-option {
    --mdc-list-list-item-container-color: var(--mat-select-panel-background-color);
  }
}

.mat-mdc-select-placeholder {
  // Delay the transition until the label has animated about a third of the way through, in
  // order to prevent the placeholder from overlapping for a split second.
  transition: color variables.$swift-ease-out-duration
      math.div(variables.$swift-ease-out-duration, 3)
      variables.$swift-ease-out-timing-function;

  @include token-utils.use-tokens(
    tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
    @include token-utils.create-token-slot(color, placeholder-text-color);
  }

  ._mat-animation-noopable & {
    transition: none;
  }

  .mat-form-field-hide-placeholder & {
    color: transparent;

    // Overwrite browser specific CSS properties that can overwrite the `color` property.
    // Some developers seem to use this approach to easily overwrite the placeholder / label color.
    -webkit-text-fill-color: transparent;

    // Remove the transition to prevent the placeholder
    // from overlapping when the label comes back down.
    transition: none;
    // Prevents the '...' from showing on the parent element.
    display: block;
  }
}

// Our MDC form field implementation is based on the MDC text field which doesn't include styles
// for select. The select specific styles are not present as they don't use their text field as a
// container. Below are the styles to account for the select arrow icon at the end.
.mat-mdc-form-field-type-mat-select {
  &:not(.mat-form-field-disabled) .mat-mdc-text-field-wrapper {
    cursor: pointer;
  }

  &.mat-form-field-appearance-fill {
    .mat-mdc-floating-label {
      max-width: calc(100% - #{$mat-select-placeholder-arrow-space});
    }

    .mdc-floating-label--float-above {
      $arrow-scale: math.div($mat-select-placeholder-arrow-space, $scale);
      max-width: calc(100% / #{$scale} - #{$arrow-scale});
    }
  }
  &.mat-form-field-appearance-outline {
    .mdc-notched-outline__notch {
      max-width: calc(100% - #{2 * ($mat-select-placeholder-arrow-space + $leading-width)});
    }

    .mdc-text-field--label-floating .mdc-notched-outline__notch {
      max-width: calc(100% - #{$leading-width * 2});
    }
  }
}

// Used to prevent inline elements from collapsing if their text bindings
// become empty. This is preferrable to inserting a blank space, because the
// space can be read out by screen readers (see #21725).
.mat-mdc-select-min-line:empty::before {
  content: ' ';
  white-space: pre;
  width: 1px;
  display: inline-block;

  // Prevents some browsers from rendering the element in high contrast mode. Use `visibility`
  // instead of `opacity` since VoiceOver + Chrome still reads out the space with the latter.
  visibility: hidden;
}

@include token-utils.use-tokens(tokens-mat-select.$prefix, tokens-mat-select.get-token-slots()) {
  .mat-form-field-appearance-fill .mat-mdc-select-arrow-wrapper {
    @include token-utils.create-token-slot(transform, arrow-transform);
  }
}
