@use 'sass:list';
@use 'sass:meta';
@use 'border-radius' as *;
@use 'box-shadow' as *;
@use 'rfs' as *;
@use '../../settings' as *;
@use '../../variables' as *;
@use '../functions' as *;
@use '../mixins' as *;
@use 'breakpoints' as *;
// This mixin uses an `if()` technique to be compatible with Dart Sass
// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details

@mixin form-validation-state-selector($state) {
  @if ($state == 'valid' or $state == 'invalid') {
    .was-validated #{if(sass(&): "&"; else: "")}:#{$state},
    #{if(sass(&): "&"; else: "")}.is-#{$state} {
      @content;
    }
  } @else {
    #{if(sass(&): "&"; else: "")}.is-#{$state} {
      @content;
    }
  }
}

@mixin form-validation-state($state, $color, $icon, $tooltip-color: color-contrast($color), $tooltip-bg-color: color-transparent($color, $form-feedback-tooltip-opacity), $focus-box-shadow: null, $border-color: $color, $focus-ring-color: focus-ring-color($color)) {
  .#{$state}-feedback {
    display: none;
    width: 100%;
    margin-top: $form-feedback-margin-top;
    @include font-size($form-feedback-font-size);
    font-style: $form-feedback-font-style;
    color: $color;
  }

  .#{$state}-tooltip {
    position: absolute;
    top: 100%;
    z-index: 5;
    display: none;
    max-width: 100%;
    padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
    margin-top: 0.1rem;
    @include font-size($form-feedback-tooltip-font-size);
    line-height: $form-feedback-tooltip-line-height;
    color: $tooltip-color;
    background-color: $tooltip-bg-color;
    @include border-radius($form-feedback-tooltip-border-radius);
  }

  @include form-validation-state-selector($state) {
    ~ .#{$state}-feedback,
    ~ .#{$state}-tooltip {
      display: block;
    }
  }

  .form-control {
    @include form-validation-state-selector($state) {
      border-color: $border-color;

      @if $enable-validation-icons {
        padding-inline-end: $input-height-inner;
        background-image: escape-svg($icon);
        background-repeat: no-repeat;
        background-position: right $input-height-inner-quarter center;
        background-size: $input-height-inner-half $input-height-inner-half;
      }

      &:focus {
        border-color: $border-color;
        @include focus-ring(true, $focus-ring-color);
        // deprecated(2.0): a `focus-box-shadow` key in `$form-validation-states`
        box-shadow: $focus-box-shadow;
      }
    }
  }

  // stylelint-disable-next-line selector-no-qualifying-type
  textarea.form-control {
    @include form-validation-state-selector($state) {
      @if $enable-validation-icons {
        padding-inline-end: $input-height-inner;
        background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
      }
    }
  }

  .form-select {
    @include form-validation-state-selector($state) {
      border-color: $border-color;

      @if $enable-validation-icons {
        &:not([multiple]):not([size]),
        &:not([multiple])[size='1'] {
          --form-select-bg-icon: #{escape-svg($icon)};
          // The icon starts at `--control-select-indicator-padding`, so the default
          // room reserves that, the icon and one padding, for every size modifier.
          // A custom icon position or a keyword icon size keeps the Sass value.
          padding-inline-end: #{if(
              sass($form-select-feedback-icon-padding-end == $form-select-padding-x * 2.5 + $form-select-indicator-padding and $form-select-feedback-icon-position == (center right $form-select-indicator-padding) and meta.type-of(list.nth($form-select-feedback-icon-size, 1)) == number): calc(
                  var(--control-select-indicator-padding) + #{list.nth($form-select-feedback-icon-size, 1)} + var(--control-padding-x)
                );
                else: $form-select-feedback-icon-padding-end
            )};
          background-position:
            var(--control-select-bg-position),
            #{if(
                sass($form-select-feedback-icon-padding-end == $form-select-padding-x * 2.5 + $form-select-indicator-padding and $form-select-feedback-icon-position == (center right $form-select-indicator-padding) and meta.type-of(list.nth($form-select-feedback-icon-size, 1)) == number): center
                  right
                  var(--control-select-indicator-padding);
                  else: $form-select-feedback-icon-position
              )};
          background-size: $form-select-bg-size, $form-select-feedback-icon-size;
        }
      }

      &:focus {
        border-color: $border-color;
        @include focus-ring(true, $focus-ring-color);
        // deprecated(2.0): a `focus-box-shadow` key in `$form-validation-states`
        box-shadow: $focus-box-shadow;
      }
    }
  }

  .form-control-color {
    @include form-validation-state-selector($state) {
      @if $enable-validation-icons {
        width: add($form-color-width, $input-height-inner);
      }
    }
  }

  .form-check-input {
    @include form-validation-state-selector($state) {
      border-color: $border-color;

      &:checked {
        background-color: $color;
      }

      &:focus {
        @include focus-ring(true, $focus-ring-color);
        // deprecated(2.0): a `focus-box-shadow` key in `$form-validation-states`
        box-shadow: $focus-box-shadow;
      }

      ~ .form-check-label {
        color: $color;
      }
    }
  }
  .form-check-inline .form-check-input {
    ~ .#{$state}-feedback {
      margin-inline-start: 0.5em;
    }
  }

  .input-group {
    > .form-control:not(:focus),
    > .form-select:not(:focus),
    > .form-floating:not(:focus-within) {
      @include form-validation-state-selector($state) {
        @if $state == 'valid' {
          z-index: 3;
        } @else if $state == 'invalid' {
          z-index: 4;
        }
      }
    }
  }
}
