@use '../../sass/expressive-menu' as menu;

// Materialize styling for the wrapper generated after select.tomselected.
.input-field:has(> select.tomselected) {
  margin-top: 16px;
}

.input-field > .ts-wrapper {
  margin-top: 5px;

  &.single > .ts-control,
  &.multi > .ts-control {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    width: 100%;
    height: 56px;
    min-height: 56px;
    padding: 0 0 0 15px !important;
    overflow: hidden;
    background: var(--md-sys-color-background) !important;
    background-image: none !important;
    border: 0 !important;
    border-bottom: 1px solid var(--md-sys-color-on-surface-variant) !important;
    border-radius: 4px 4px 0 0;
    box-shadow: none !important;
  }

  &.focus > .ts-control {
    border-bottom: 2px solid var(--input-color) !important;
  }

  .ts-control {
    font-size: 16px;
    color: var(--md-sys-color-on-surface);

    > input,
    input[role="combobox"] {
      box-sizing: border-box;
      width: auto !important;
      height: auto !important;
      min-height: 0 !important;
      margin: 0 !important;
      padding: 0 !important;
      color: var(--md-sys-color-on-surface) !important;
      font-size: 16px;
      line-height: 24px;
      background: transparent !important;
      border: 0 !important;
      border-radius: 0 !important;
      box-shadow: none !important;

      &::placeholder {
        color: color-mix(in srgb, var(--md-sys-color-on-surface) 55%, transparent);
        opacity: 1;
      }
    }
  }

  // Only multi-select values are rendered as chips. A single value remains
  // normal input text, matching Materialize's select and text fields.
  &.multi > .ts-control {
    gap: 6px;
    padding: 0 0 0 15px !important;
    flex-wrap: nowrap;

    .item {
      flex: 0 0 auto;
      margin: 0 !important;
      padding: 4px 10px !important;
      color: var(--md-sys-color-on-primary-container);
      line-height: 20px;
      background: var(--md-sys-color-primary-container);
      border: 1px solid var(--md-sys-color-outline-variant);
      border-radius: 999px;
    }
  }

  &.single > .ts-control .item {
    margin: 0 !important;
    padding: 0 !important;
    color: var(--md-sys-color-on-surface);
    line-height: 24px;
    background: transparent;
    border: 0;
  }

  &.disabled > .ts-control {
    opacity: 1;
    color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);
    background: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 4%) !important;
    border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%) !important;
  }

  // Tom Select hides the native caret, so draw one centered in the field.
  &.single > .ts-control::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 24px;
    width: 9px;
    height: 9px;
    margin-top: -6px;
    border: solid var(--md-sys-color-on-surface) !important;
    border-width: 0 3px 3px 0 !important;
    transform: rotate(45deg);
  }

  &.single.dropdown-active > .ts-control::after {
    margin-top: -3px;
    transform: rotate(-135deg);
  }
}

// Large multi-value sets can either grow onto additional rows or retain the
// standard field height and expose a horizontal scrollbar.
.input-field > select.tomselected[data-select-overflow="wrap"] + .ts-wrapper.multi > .ts-control {
  height: auto;
  min-height: 56px;
  padding: 8px 0 8px 15px !important;
  overflow: visible;
  flex-wrap: wrap;
}

.input-field > select.tomselected[data-select-overflow="scroll"] + .ts-wrapper.multi > .ts-control {
  overflow-x: auto;
  overflow-y: hidden;
  flex-wrap: nowrap;
  scrollbar-color: var(--md-sys-color-outline) transparent;
  scrollbar-width: thin;

  &::-webkit-scrollbar {
    height: 5px;
  }

  &::-webkit-scrollbar-thumb {
    background: var(--md-sys-color-outline);
    border-radius: 999px;
  }
}

// Tom Select labels have the same two states as Materialize text fields.
// State 1: no value and no placeholder — label acts as the in-field prompt.
.input-field > select.tomselected + .ts-wrapper + label {
  position: absolute !important;
  top: 16px !important;
  left: 16px !important;
  z-index: 2;
  margin: 0 !important;
  padding: 0 !important;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 16px !important;
  line-height: 24px !important;
  text-align: left !important;
  background: transparent;
  transform: none !important;
  transform-origin: top left !important;
  transition: top 0.2s ease-out, transform 0.2s ease-out, color 0.2s ease-out;
}

// State 2: a placeholder, a selected value, or focus — float from the same
// 16px base font/position used by Materialize text-input labels.
.input-field > select.tomselected[placeholder]:not([placeholder=""]) + .ts-wrapper + label,
.input-field > select.tomselected:has(> option[value=""]:checked:not(:empty)) + .ts-wrapper + label,
.input-field > select.tomselected + .ts-wrapper.has-items + label,
.input-field > select.tomselected + .ts-wrapper.focus + label {
  position: absolute !important;
  top: -12px !important;
  left: 16px !important;
  font-size: 16px !important;
  transform: scale(0.75) !important;
}

.input-field > select.tomselected + .ts-wrapper.focus + label {
  color: var(--input-color);
}

// Outlined fields use the same two states; only the floating position changes
// so the small label cuts a notch through the outline like a text input.
.input-field.outlined > .ts-wrapper.single > .ts-control,
.input-field.outlined > .ts-wrapper.multi > .ts-control {
  padding: 0 0 0 15px !important;
  background: transparent !important;
  border: 1px solid var(--md-sys-color-on-surface-variant) !important;
  border-radius: 4px;
}

.input-field.outlined > .ts-wrapper.focus > .ts-control {
  border: 2px solid var(--input-color) !important;
}

.input-field.outlined > select.tomselected[placeholder]:not([placeholder=""]) + .ts-wrapper + label,
.input-field.outlined > select.tomselected:has(> option[value=""]:checked:not(:empty)) + .ts-wrapper + label,
.input-field.outlined > select.tomselected + .ts-wrapper.has-items + label,
.input-field.outlined > select.tomselected + .ts-wrapper.focus + label {
  top: -8px !important;
  left: 12px !important;
  padding: 0 4px !important;
  line-height: 16px !important;
  background: var(--md-sys-color-surface);
  transform: scale(0.75) !important;
}

div.suffix.suffix-tomselect {
  z-index: 2;
  top: 30px;
}

// Keep the enhanced control and its label in the parent field's error state.
.input-field.error > .ts-wrapper > .ts-control,
.input-field.outlined.error > .ts-wrapper > .ts-control {
  border-color: var(--md-sys-color-error) !important;
}
.input-field.error > select.tomselected + .ts-wrapper + label,
.input-field.error > select.tomselected + .ts-wrapper.focus + label {
  color: var(--md-sys-color-error);
}

/// Share the Expressive menu surface even when Tom Select portals it to body.
.ts-dropdown {
  @include menu.surface;

  z-index: 9999;
  margin-top: 4px;
  overflow: hidden;
  font-family: inherit;
  font-size: 16px;
  line-height: 24px;
  letter-spacing: 0.5px;

  .ts-dropdown-content {
    padding: 2px 4px;
    background: inherit;
    scroll-padding-block: 2px;
  }

  /// Keep option groups readable without vendor borders or white headers.
  .optgroup {
    border: 0;
    opacity: 1;

    /// Use the shared disabled text color without a second vendor opacity layer.
    &[data-disabled] .option { opacity: 1; }

    + .optgroup {
      margin-top: 4px;
      padding-top: 4px;
      border-top: 1px solid var(--md-sys-color-outline-variant);
    }
  }

  .optgroup-header {
    padding: 12px;
    color: var(--md-sys-color-on-surface-variant);
    background: transparent;
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
  }

  .option, .create, .no-results {
    @include menu.item;

    position: relative;
    display: block;
    padding: 12px;
    font-size: 16px;
    line-height: 24px;
    opacity: 1;

    + :is(.option, .create, .no-results) { margin-top: 2px; }

    &:first-child, &:is(.optgroup-header + *) {
      border-top-left-radius: 12px;
      border-top-right-radius: 12px;
    }

    &:last-child {
      border-bottom-left-radius: 12px;
      border-bottom-right-radius: 12px;
    }

    /// Persistent selection stays distinct from the keyboard cursor.
    &.selected {
      @include menu.selected;
    }

    &[data-selectable]:not([aria-disabled="true"], [data-disabled], [data-disabled] *) {
      &:hover { @include menu.state-layer(8%); }

      &.active {
        color: var(--menu-item-color);
        @include menu.state-layer;
        @include menu.focus-ring;
      }
    }

    /// Tom Select marks disabled options and disabled groups separately.
    &[aria-disabled="true"], &[data-disabled], &:is([data-disabled] *) {
      color: color-mix(in srgb, var(--menu-item-color) 38%, transparent);
      opacity: 1;
      cursor: default;
    }
  }

  .no-results { color: var(--md-sys-color-on-surface-variant); }

  [data-selectable] .highlight {
    color: inherit;
    background: color-mix(in srgb, var(--menu-item-color) 12%, transparent);
  }
}

/// Icon templates work in both inline and portalled menus and selected values.
.ts-dropdown .ts-option-content,
.input-field > .ts-wrapper .ts-option-content {
  display: flex;
  align-items: center;
  gap: 8px;

  img {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    object-fit: cover;
    border-radius: 50%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ts-dropdown :is(.option, .create, .no-results) { transition: none; }
}

@media (forced-colors: active) {
  .ts-dropdown {
    border: 1px solid CanvasText;

    [data-selectable].active {
      outline: 3px solid Highlight;
      outline-offset: -3px;
    }
  }
}
