@use 'sass:math';

// Single checkable element ----------------------------------------------------

.lf-checkable .custom-control {
  display: flex;

  // Show a pointer cursor when the checkable is not read-only
  &:not(.is-readonly) {
    cursor: pointer;
  }

  // Position and animate checkable
  padding-left: $input-btn-padding-x-sm + $custom-control-gutter +
    $custom-control-indicator-size;
  .custom-control-label::before,
  .custom-control-label::after {
    @include transition($input-transition);
    top: 50%;
    margin-top: math.div(-$custom-control-indicator-size, 2);
  }

  // Center description
  .custom-control-label {
    @include transition($input-transition);
    display: flex;
    align-items: center;
    line-height: $display-line-height;
  }

  // Style boxed area similarly to other read-only inputs
  &.is-readonly {
    background-color: $input-disabled-bg;
    .custom-control-label {
      color: $custom-control-label-disabled-color;
    }
  }

  // Styles for warning inputs
  &.is-warning {
    // Change checkable colours to match the invalid style
    .custom-control-input {
      & ~ .custom-control-label::before {
        border-color: $form-feedback-warning-color;
      }
      &:focus ~ .custom-control-label::before {
        box-shadow: 0 0 0 1px $body-bg,
          0 0 0 $input-btn-focus-width rgba($form-feedback-warning-color, 0.25);
      }
      &:checked {
        & ~ .custom-control-label::before {
          background-color: $form-feedback-warning-color;
        }
      }
      &:active ~ .custom-control-label::before {
        border-color: lighten($form-feedback-warning-color, 20%);
        background-color: lighten($form-feedback-warning-color, 20%);
      }
    }
    // Style "indeterminate" background only for checkboxes
    .custom-control-input[type='checkbox']:indeterminate {
      background-color: $form-feedback-warning-color;
    }

    // Styles for read-only inputs
    &.is-readonly {
      background-color: $form-feedback-warning-disabled-bg;
    }

    // Read-only invalid input styles
    &.is-readonly .custom-control-input {
      & ~ .custom-control-label {
        color: $form-feedback-warning-color;
      }
      & ~ .custom-control-label::before {
        background-color: $form-feedback-warning-disabled-bg;
      }
      &:checked,
      &:indeterminate {
        & ~ .custom-control-label::before {
          background-color: lighten($form-feedback-warning-color, 20%);
        }
      }
    }
  }

  // Styles for invalid inputs
  &.is-invalid {
    // Change checkable colours to match the invalid style
    .custom-control-input {
      & ~ .custom-control-label::before {
        border-color: $form-feedback-invalid-color;
      }
      &:focus ~ .custom-control-label::before {
        box-shadow: 0 0 0 1px $body-bg,
          0 0 0 $input-btn-focus-width rgba($form-feedback-invalid-color, 0.25);
      }
      &:checked {
        & ~ .custom-control-label::before {
          background-color: $form-feedback-invalid-color;
        }
      }
      &:not(:disabled):active ~ .custom-control-label::before {
        border-color: lighten($form-feedback-invalid-color, 20%);
        background-color: lighten($form-feedback-invalid-color, 20%);
      }
    }
    // Style "indeterminate" background only for checkboxes
    .custom-control-input[type='checkbox']:indeterminate {
      background-color: $form-feedback-invalid-color;
    }

    // Read-only invalid input styles
    &.is-readonly .custom-control-input {
      & ~ .custom-control-label {
        color: $form-feedback-invalid-color;
      }
      & ~ .custom-control-label::before {
        background-color: $form-feedback-invalid-disabled-bg;
      }
      &:checked,
      &:indeterminate {
        & ~ .custom-control-label::before {
          background-color: lighten($form-feedback-invalid-color, 20%);
        }
      }
    }
  }

  // When the input does not have a code remove the border and paddings
  &:first-child {
    min-height: $custom-control-indicator-size + 2 * $input-btn-padding-y-sm;
    border: 0;

    // Align to left when not read-only
    &:not(.is-readonly) {
      padding: 0 0 0 $custom-control-gutter + $custom-control-indicator-size;
    }
  }
}

// Group of checkable elements -------------------------------------------------

.lf-checkable-group .lf-checkables {
  display: block;
  padding: 0;

  // Style groups with no/pending options
  .no-options,
  .pending-options {
    padding: $input-btn-padding-y-sm $input-btn-padding-x-sm;
  }
  .no-options {
    color: $text-muted;
  }
  .pending-options {
    @include loading($pending-size, $pending-border-size);
    margin-top: math.div($spacer, 3);
  }

  // Remove all border radius since it is easier to set it where appropriate
  .input-group-text,
  .custom-control {
    margin: 0; // Override Bootstrap margin
    border-radius: 0;
  }

  // Styles for "block" checkable group
  .lf-checkable {
    // Remove extra borders
    &:not(:first-child) {
      .input-group-text,
      .custom-control {
        border-top-width: 0;
      }
    }
    // Set border radius
    &:first-child {
      .input-group-text,
      .custom-control:first-child {
        border-top-left-radius: $input-border-radius;
      }
      .custom-control {
        border-top-right-radius: $input-border-radius;
      }
    }
    &:last-child {
      .input-group-text,
      .custom-control:first-child {
        border-bottom-left-radius: $input-border-radius;
      }
      .custom-control {
        border-bottom-right-radius: $input-border-radius;
      }
    }
    .custom-control:first-child:not(.is-readonly) {
      padding: $input-btn-padding-y-sm 0 $input-btn-padding-y-sm
        $custom-control-gutter + $custom-control-indicator-size;
    }
  }

  // Styles for "inline" checkable groups (non-small screens only), these are
  // built on top of the "block" styles, so some styles have to be reset
  @include media-breakpoint-up(md) {
    &.display-inline {
      display: inline-flex;

      .lf-checkable {
        // Remove extra borders
        &:not(:first-child) {
          .input-group-text,
          .custom-control {
            border-top-width: 1px; // Reset "block" style
          }
          .input-group-text,
          .custom-control:first-child {
            border-left-width: 0;
          }
        }
        // Set border radius
        &:first-child {
          .input-group-text,
          .custom-control:first-child {
            border-bottom-left-radius: $input-border-radius;
          }
          .custom-control {
            border-top-right-radius: 0; // Reset "block" style
          }
        }
        &:last-child {
          .input-group-text,
          .custom-control:first-child {
            border-bottom-left-radius: 0; // Reset "block" style
          }
          .custom-control {
            border-top-right-radius: $input-border-radius;
          }
        }
      }
    }
  }

  // When the checkable group has a code
  &:not(:first-child) {
    // Style groups with no/pending options
    .no-options,
    .pending-options {
      margin-left: auto;
      margin-right: auto;
    }

    // Undo checkable padding
    .lf-checkable .custom-control:first-child:not(.is-readonly) {
      padding: $input-btn-padding-y-sm $input-btn-padding-x-sm
        $input-btn-padding-y-sm $input-btn-padding-x-sm + $custom-control-gutter +
        $custom-control-indicator-size;
    }

    // Styles for "block" checkable group
    .lf-checkable {
      // Remove bounding borders and border radius from left side
      &:first-child {
        .custom-control:first-child {
          margin-top: $input-btn-padding-y-sm;
        }
        .input-group-text,
        .custom-control {
          border-top-width: 0;
          border-top-left-radius: 0;
        }
      }
      &:last-child {
        .custom-control:first-child {
          margin-bottom: $input-btn-padding-y-sm;
        }
        .input-group-text,
        .custom-control {
          border-bottom-width: 0;
          border-bottom-left-radius: 0;
        }
      }
      .input-group-text,
      .custom-control:first-child {
        border-left-width: 0;
      }
      .custom-control {
        border-right-width: 0;
      }
    }

    // Styles for "inline" checkable groups (non-small screens only), these
    // are built on top of the "block" styles, so some styles have to be
    // reset
    @include media-breakpoint-up(md) {
      &.display-inline {
        .lf-checkable {
          // Remove bounding borders and border radius from left side
          &:first-child {
            .input-group-text,
            .custom-control:first-child {
              border-left-width: 0;
              border-bottom-left-radius: 0;
            }
          }
          &:last-child .custom-control {
            border-right-width: 0;
          }
          .input-group-text,
          .custom-control {
            border-top-width: 0;
            border-bottom-width: 0;
          }
          // Reset "block" style
          .custom-control {
            border-right-width: 1px;
            &:first-child {
              margin: 0;
            }
          }
        }
      }
    }
  }

  // When the checkable group does not have a code
  &:first-child {
    border: 0;
  }
}
