@use 'sass:math';
@use '@angular/cdk';

@use '../core/style/variables';
@use '../core/style/vendor-prefixes';
@use '../core/tokens/m2/mat/datepicker' as tokens-mat-datepicker;
@use '../core/tokens/token-utils';

$date-range-input-separator-spacing: 4px;
$date-range-input-part-max-width: calc(50% - #{$date-range-input-separator-spacing});
$_tokens: tokens-mat-datepicker.$prefix, tokens-mat-datepicker.get-token-slots();

@mixin _placeholder-transition($property) {
  transition: #{$property} variables.$swift-ease-out-duration
    math.div(variables.$swift-ease-out-duration, 3)
    variables.$swift-ease-out-timing-function;
}

// Host of the date range input.
.mat-date-range-input {
  display: block;
  width: 100%;
}

// Inner container that wraps around all the content.
.mat-date-range-input-container {
  display: flex;
  align-items: center;
}

// Text shown between the two inputs.
.mat-date-range-input-separator {
  @include _placeholder-transition(opacity);
  margin: 0 $date-range-input-separator-spacing;

  @include token-utils.use-tokens($_tokens...) {
    @include token-utils.create-token-slot(color, range-input-separator-color);

    .mat-form-field-disabled & {
      @include token-utils.create-token-slot(color, range-input-disabled-state-separator-color);
    }
  }

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

.mat-date-range-input-separator-hidden {
  // Disable text selection, because the user can click
  // through the main label when the input is disabled.
  @include vendor-prefixes.user-select(none);

  // Use opacity to hide the text, because `color: transparent` will be shown in high contrast mode.
  opacity: 0;
  transition: none;
}

// Wrapper around the inner inputs. Used to facilitate the auto-resizing input.
.mat-date-range-input-wrapper {
  position: relative;
  overflow: hidden;
  max-width: $date-range-input-part-max-width;
}

.mat-date-range-input-end-wrapper {
  // Allow the end input to fill the rest of the available space.
  flex-grow: 1;
}

// Underlying input inside the range input.
.mat-date-range-input-inner {
  position: absolute;
  top: 0;
  left: 0;

  // Reset the input so it's just a transparent rectangle.
  font: inherit;
  background: transparent;
  color: currentColor;
  border: none;
  outline: none;
  padding: 0;
  margin: 0;
  vertical-align: bottom;
  text-align: inherit;
  -webkit-appearance: none;
  width: 100%;

  // Does nothing on Chrome, but necessary for the text
  // to align in some cases on Safari and Firefox.
  height: 100%;

  // Undo the red box-shadow glow added by Firefox on invalid inputs.
  // See https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid
  &:-moz-ui-invalid {
    box-shadow: none;
  }

  @include vendor-prefixes.input-placeholder {
    @include _placeholder-transition(color);
  }

  @include token-utils.use-tokens($_tokens...) {

    &[disabled] {
      @include token-utils.create-token-slot(color, range-input-disabled-state-text-color);
    }
  }

  .mat-form-field-hide-placeholder &,
  .mat-date-range-input-hide-placeholders & {
    @include vendor-prefixes.input-placeholder {
      // Disable text selection, because the user can click
      // through the main label when the input is disabled.
      @include vendor-prefixes.user-select(none);

      // Needs to be !important, because the placeholder will end up inheriting the
      // input color in IE, if the consumer overrides it with a higher specificity.
      color: transparent !important;
      -webkit-text-fill-color: transparent;
      transition: none;

      @include cdk.high-contrast {
        // In high contrast mode the browser will render the
        // placeholder despite the `color: transparent` above.
        opacity: 0;
      }
    }
  }

  ._mat-animation-noopable & {
    @include vendor-prefixes.input-placeholder {
      transition: none;
    }
  }
}

// We want the start input to be flush against the separator, no matter how much text it has, but
// the problem is that inputs have a fixed width. We work around the issue by implementing an
// auto-resizing input that stretches based on its text, up to a point. It works by having
// a relatively-positioned wrapper (`.mat-date-range-input-wrapper` below) and an absolutely-
// positioned `input`, as well as a `span` inside the wrapper which mirrors the input's value and
// placeholder. As the user is typing, the value gets mirrored in the span which causes the wrapper
// to stretch and the input with it.
.mat-date-range-input-mirror {
  // Disable user selection so users don't accidentally copy the text via ctrl + A.
  @include vendor-prefixes.user-select(none);

  // Hide the element so it doesn't get read out by screen
  // readers and it doesn't show up behind the input.
  visibility: hidden;

  // Text inside inputs never wraps so the one in the span shouldn't either.
  white-space: nowrap;
  display: inline-block;

  // Prevent the container from collapsing. Make it more
  // than 1px so the input caret doesn't get clipped.
  min-width: 2px;
}

.mat-mdc-form-field-type-mat-date-range-input .mat-mdc-form-field-infix {
  // Bump the default width slightly since it's somewhat cramped with two inputs and a separator.
  width: 200px;
}
