@use "sass:math";

@import '../icons';

$form-control-icon-size: 1rem;
$form-control-font-size: 1rem;
$form-control-icon-position: .5rem center;
$form-control-label-size: var(--ec-font-size-label);
$form-control-height: 2rem;
$form-control-line-height: 1.25rem;
$form-control-padding-x: .5rem;
$form-control-spacing-y: 1rem;
$form-control-padding-y: .3125rem;

$checkbox-indicator-size: $form-control-icon-size;

@mixin form-control-input-base {
  &::selection {
    background-color: var(--ec-form-control-background-color-selection);
    color: var(--ec-form-control-color-selection);
  }
  &::-webkit-input-placeholder { /* Chrome/Opera/Safari */
    color: var(--ec-form-control-color-placeholder);
  }
  &::-moz-placeholder { /* Firefox 19+ */
    color: var(--ec-form-control-color-placeholder);
    opacity: 1;
  }
  &:-ms-input-placeholder { /* IE 10+ */
    color: var(--ec-form-control-color-placeholder);
  }
  &:-moz-placeholder { /* Firefox 18- */
    color: var(--ec-form-control-color-placeholder);
    opacity: 1;
  }
}

@mixin form-control-input-group-invalid {
  .textbox-group-input ::ng-deep .control input.ng-invalid,
  .textbox-group-input ::ng-deep .control input.ng-valid {
    @include form-control-state(invalid, input);

    background-image: none;

    & ~ .icon-invalid {
      display: inline-flex;
      position: absolute;
      left: .5rem;
      top: .5rem;
      z-index: 1;
    }

    & ~ .icon-required {
      display: none
    }
  }

  &:not(.open) {
    .textbox-group-btn-right ::ng-deep button{
      &:not(:focus) {
        border-color: var(--ec-form-control-border-color-invalid);
      }
      background-color: var(--ec-form-control-background-color-invalid);
    }
  }
}

/// Calculate the background properties for an input icon
/// @param {string} $icon - The classname of the icon (matches the filename)
/// @param {number} $width [$form-control-icon-size] - The width of the icon, converted to ems
/// @param {number} $height [$form-control-icon-size] - The height of the icon, converted to ems
/// @param {string|number|list} $position [$form-control-icon-position] - The background-position of the icon
/// @param {number} $indent [$form-control-icon-size] - The amount to indent the text to allow room for the icon
@mixin form-control-input-icon(
  $icon,
  $width: $form-control-icon-size,
  $height: $form-control-icon-size,
  $position: $form-control-icon-position,
  $indent: $form-control-icon-size + .25rem,
) {
  $size: $width, $height;
  @include icon-bg-image($icon, $position, $size);
  padding-left: ($indent + $form-control-padding-x);
}

@mixin form-control-state($state, $selector) {
  $icon-position: $form-control-icon-position;

  @if $selector == textarea {
    $icon-position: .5rem .5rem;
  }

  /// Required
  @if $state == required {
    // TODO: remove when all bootstrap and kendo controls have been replaced in EUM
    @include form-control-input-icon($required-icon, $position: $icon-position);

  /// Pending
  } @else if $state == pending {

    // TODO: remove when all bootstrap and kendo controls have been replaced in EUM
    @include form-control-input-icon(pending-icon(), $position: $icon-position);

  /// Invalid
  } @else if $state == invalid {
    background-color: var(--ec-form-control-background-color-invalid);
    border-color: var(--ec-form-control-border-color-invalid);
    
    &:focus {
      border-color: var(--ec-form-control-background-color-invalid);
    }

    // TODO: remove when all bootstrap and kendo controls have been replaced in EUM
    @include form-control-input-icon($invalid-icon, $position: $icon-position);

  /// Focus
  } @else if $state == focus {
    border-color: var(--ec-form-control-border-color-focus);
    box-shadow: var(--ec-form-control-box-shadow-focus);
    position: relative;
    z-index: 1;

  /// Disabled
  } @else if $state == disabled {
    background-color: var(--ec-form-control-background-color-disabled);
    border-color: var(--ec-form-control-border-color-disabled);
    color: var(--ec-form-control-color-disabled);
    opacity: var(--ec-form-control-opacity-disabled);

    &:required,
    &:required.is-empty {
      background-image: none;
      padding-left: $form-control-padding-x;

      // We need to define these again because the :required styles override
      // the background-color and border-color we set above
      background-color: var(--ec-form-control-background-color-disabled);
      border-color: var(--ec-form-control-border-color-disabled);

      & + .icon-required {
        display: none;
      }
    }
  }
}

/// A form control label
@mixin form-control-label {
  color: var(--ec-form-control-label-color, var(--ec-color-secondary-dark));
  display: block;
  font-size: $form-control-label-size;
  line-height: 1;
  margin: calc(#{$form-control-label-size} / 2) 0;
}

/// The default form control element in the control component
/// @param {string} $tag [input] - The HTML tag name of the input element (e.g. input, textarea)
@mixin form-control-input($selector: input, $new-state-icons: false) {
  @include form-control-input-base;
  background-color: var(--ec-form-control-background-color);
  border: 1px solid var(--ec-form-control-border-color);
  border-radius: var(--ec-border-radius);
  background-image: none;
  background-clip: padding-box;
  width: 100%;
  line-height: $form-control-line-height;
  padding: $form-control-padding-y $form-control-padding-x;

  @if $selector == input {
    height: $form-control-height;
  } @else {
    height: auto;
  }

  & ~ .icon-required,
  & ~ .icon-invalid {
    color: var(--ec-form-control-border-color-invalid);
  }

  &:required {
    &.is-empty {
      @include form-control-state(required, $selector);

      @if $new-state-icons {
        background-image: none;

        & ~ .icon-required {
          display: inline-flex;
          position: absolute;
          left: .5rem;
          top: .5rem;
          z-index: 1;
        }
      }
    }
  }

  // Use .ng-invalid because not all Angular validators trigger :invalid
  &.ng-invalid {
    &.ng-touched {
      @include form-control-state(invalid, $selector);

      @if $new-state-icons {
        background-image: none;

        & ~ .icon-invalid {
          display: inline-flex;
          position: absolute;
          left: .5rem;
          top: .5rem;
          z-index: 1;
        }
  
        & ~ .icon-required {
          display: none
        }
      }
    }
  }

  &.is-pending {
    &.ng-valid,
    &.ng-invalid,
    &.ng-pending {
      @include form-control-state(pending, $selector);

      @if $new-state-icons {
        & ~ .icon-loading {
          display: inline-flex;
          position: absolute;
          left: .5rem;
          top: .5rem;
          z-index: 1;
        }

        & ~ .icon-required,
        & ~ .icon-invalid {
          display: none;
        }
      }
    }
  }

  &:focus,
  &:focus.is-empty {
    @include form-control-state(focus, $selector);
  }

  &:disabled {
    @include form-control-state(disabled, $selector);
  }

  &.is-uppercase:not(.is-empty) {
    text-transform: uppercase;
  }
}

/// The base styles of a control component. These styles will be applied to :host
@mixin form-control-base() {
  color: var(--ec-form-control-color);
  // font-family: $control-font-family;
  font-size: var(--ec-form-control-font-size);
  display: block;
  margin-bottom: 1rem;
  width: 100%;

  :host-context(.form-condensed) {
   margin-bottom: .5rem;
  }

  .control {
    width: 100%;
    display: flex;
    flex-direction: column;

    &.control-label-bottom {
      flex-direction: column-reverse;
    }

    &.control-label-left {
      flex-direction: row;
      label {
        margin-right: .25rem;
      }
    }

    &.control-label-right {
      flex-direction: row-reverse;
      label {
        margin-left: .25rem;
      }
    }

    &.control-label-left,
    &.control-label-right {
      align-items: center;

      label {
        flex: 1 1;
        margin-top: 0;
        margin-bottom: 0;
      }
      .control-input {
        flex: 2 2;
      }
    }

    &.is-readonly {
      input,
      select,
      textarea {
        @include form-control-read-only;
      }
    }

    &.invalid {
      @include form-control-input-group-invalid;
    }
  }

  .textbox-group {
    display: flex;
    position: relative;
  }

  textarea:focus,
  input:focus,
  select:focus {
    outline: none;
  }
}

@mixin checkbox-radio {
  cursor: pointer;
  display: inline-flex;
  margin-bottom: 0;
  position: relative;
}

@mixin checkbox-radio-input(
  $type,
  $indicator-selector: '.indicator',
  $label-selector: '.label'
) {
  margin-top: .5rem;
  opacity: 0;
  position: absolute;
  z-index: -1;

  &:not(:checked) {
    + #{$indicator-selector} {
      color: var(--ec-form-control-border-color);

      &::before {
        display: none;
      }
    } 
  }

  @if $type == 'checkbox' {
    &.indeterminate,
    &:indeterminate {
      + #{$indicator-selector} {
        color: var(--ec-color-interactive);

        &::before {
          content: '';
          background-color: currentColor;
          display: block;
          width: 10px;
          height: 3px;
        }
      }
    }
  }

  &:focus {
    + #{$indicator-selector} {
      color: var(--ec-color-interactive);
      box-shadow: var(--ec-form-control-box-shadow-focus);
      border-color: var(--ec-form-control-border-color-focus);
    }
  }

  &:disabled {
    + #{$indicator-selector} {
      color: var(--ec-form-control-color-disabled);
      background-color: var(--ec-form-control-background-color-disabled);
      border-color: var(--ec-form-control-border-color-disabled);
      opacity: var(--ec-form-control-opacity-disabled);
    }

    ~ #{$label-selector} {
      color: var(--ec-form-control-color-disabled);
      opacity: var(--ec-form-control-opacity-disabled);
    }
  }
}

@mixin checkbox-radio-indicator($type) {
  background-color: var(--ec-form-control-background-color);
  background-clip: padding-box;
  border: 1px solid currentColor;
  color: var(--ec-color-interactive);
  margin-top: .5rem;
  flex: none;
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 1em;
  width: 1em;

  @if $type == 'radio' {
    border-radius: 50%;

    &::before {
      background-color: currentColor;
      content: "";
      display: block;
      width: .5em;
      height: .5em;
      border-radius: 50%;
    }

  } @else {
    border-radius: .125rem;

    &::before {
      font-size: .6875em;
    }
  }
}

@mixin checkbox-radio-label() {
  line-height: $form-control-line-height;
  padding: 0.375rem 0;
  margin-left: .5rem;
  min-height: $form-control-height;
  height: auto;
}

@mixin checkbox-radio-readonly(
  $input-selector: '.input',
  $indicator-selector: '.indicator',
  $label-selector: '.label'
) {
  pointer-events: none;

  #{$input-selector} {
    opacity: 0;
  }

  #{$indicator-selector} {
    background-color: var(--ec-form-control-background-color-readonly);
    border-color: var(--ec-form-control-border-color-readonly);
  }

  #{$label-selector},
  #{$indicator-selector} {
    opacity: 1;
    color: var(--ec-form-control-color);
  }
}

@mixin toggle() {
  font-size: var(--ec-form-control-font-size);
  background-color: var(--ec-border-color);
  border-radius: var(--ec-border-radius);
  border: 1px solid var(--ec-border-color);
  min-height: 2em;
  position: relative;
  color: var(--ec-color-secondary-dark);
  display: flex;

  input {
    position: absolute;
    z-index: -1;
    opacity: 0;

    &:checked {
      & + label {
        color: var(--ec-color-interactive);
      }

      &:last-of-type {
        & ~ a {
          transform: translateX(100%);
        }
      }
    }

    &:focus ~ .toggle-focused {
      display: block;
    }
  }

  .toggle-focused {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    box-shadow: var(--ec-form-control-box-shadow-focus);
    border-radius: var(--ec-form-control-border-radius);
    display: none;
  }

  label {
    align-items: center;
    cursor: pointer;
    display: flex;
    flex: 1 1 0%;
    justify-content: center;
    line-height: 1.1em;
    margin-bottom: 0;
    padding: 0.375rem .5rem;
    position: relative;
    text-align: center;
    transition: color .3s ease;
    z-index: 2;

    .ec-icon {
      color: inherit;
    }
  }

  a {
    border: 0.1875rem solid transparent;
    border-radius: calc(var(--ec-form-control-border-radius) * .75);
    display: block;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    transition: transform .25s ease;
    width: 50%;
    z-index: 1;

    .toggle-handle {
      background-color: var(--ec-form-control-background-color);
      border-radius: calc(var(--ec-form-control-border-radius) * .75);
      height: 100%;
    }
  }

  &.is-disabled {
    opacity: var(--ec-form-control-opacity-disabled);
    color: var(--ec-form-control-color-disabled);

    label {
      color: inherit !important;
      cursor: default;
    }
  }
}

@mixin toggle-options {
  @each $count in (3,4,5) {
    .toggle-options-#{$count} {
      a {
        width: percentage(math.div(1, $count));
      }

      input:checked:last-of-type ~ a {
        transform: translateX(percentage($count - 1));
      }

      @while $count > 2 {
        $count: $count - 1;
        input:checked:nth-of-type(#{$count}) ~ a {
          transform: translateX(percentage($count - 1));
        }
      }
    }
  }
}

@mixin form-heading() {
  @include form-control-label;
  font-weight: bold;
}

// Override the presentation of children controls when the parent control is
// untouched
@mixin form-control-untouched {
  input {
    &.ng-invalid.ng-touched {
      background-image: none;
      padding-left: $form-control-padding-x;

      &:not(.is-empty) ~ .units-left {
        left: 0;
      }
    }
    &:required:not(:disabled).is-empty {
      @include form-control-state(required, input);

      &:focus {
        @include form-control-state(focus, input);
      }
    }
  }
}

// Shared styles for controls that include a popup when the popup is open (combobox, dateinput)
@mixin form-control-open() {
  .textbox-group {
    ec-textbox {
      --ec-form-control-box-shadow-focus: none;
      --ec-form-control-border-color-focus: var(--ec-form-control-border-color);
    }

    ec-button {
      --ec-button-box-shadow-focus-secondary: none;
      --ec-button-background-color-secondary: var(--ec-background-color-selected);
    }
  }
}

@mixin form-control-read-only {
  border-color: var(--ec-form-control-border-color-readonly);
  background-color: var(--ec-form-control-background-color-readonly);
  background-clip: border-box;
  background-image: none;
  color: var(--ec-form-control-color-readonly);
  opacity: 1;
  user-select: none;
  pointer-events: none;
  overflow: hidden;
  white-space: nowrap;
}

@mixin form-control-popup {
  background-color: var(--ec-background-color);
  border-radius: var(--ec-border-radius-card);
  box-shadow: var(--ec-box-shadow-overlay);
  margin-top: .25rem;
  overflow: hidden;
  z-index: var(--ec-z-index-popup);
}