//
// Copyright IBM Corp. 2021
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@use 'box-shadow' as *;
@use 'convert';
@use 'focus-outline' as *;
@use 'z-index' as *;
@use '../config' as *;
@use '../motion' as *;
@use '../spacing' as *;
@use '../theme' as *;
@use '../type';

// Tooltip
// Tooltip caret visual styles
/// @access public
/// @group tooltip
@mixin tooltip--caret {
  position: absolute;
  z-index: z('floating');
  border-style: solid;
  block-size: 0;
  content: '';
  inline-size: 0;
}

// Tooltip
// Tooltip content box visual styles
/// @param {String} $tooltip-type ['icon'] - The type, from: `icon`, `definition`
/// @access public
/// @group tooltip
@mixin tooltip--content($tooltip-type: 'icon') {
  @include box-shadow;

  z-index: z('floating');
  @if $tooltip-type == 'definition' {
    padding: $spacing-03 $spacing-05;
  } @else {
    padding: convert.to-rem(3px) $spacing-05;
  }

  border-radius: convert.to-rem(2px);
  background-color: $background-inverse;
  block-size: auto;
  color: $text-inverse;
  font-weight: 400;
  inline-size: max-content;
  max-inline-size: convert.to-rem(208px);
  min-inline-size: convert.to-rem(24px);
  text-align: start;
  transform: translateX(-50%);
  @include type.type-style('body-compact-01');

  // IE media query
  @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
    inline-size: auto;
  }
  // Edge 12-15 and Edge 16 feature queries
  @supports (-ms-accelerator: true) {
    inline-size: auto;
  }
  @supports (-ms-ime-align: auto) {
    inline-size: auto;
  }

  // Windows, Firefox HCM Fix
  @media screen and (-ms-high-contrast: active), screen and (prefers-contrast) {
    border: 1px solid transparent;
  }
}

// Tooltip
// Definition and Icon CSS only tooltip
/// @param {String} $tooltip-type ['icon'] - The type, from: `icon`, `definition`
/// @param {String} $position ['bottom'] - The position, from: `top`, `right`, `bottom`, `left`
/// @access public
/// @group tooltip
@mixin tooltip--trigger($tooltip-type: 'icon', $position: 'bottom') {
  position: relative;
  display: inline-flex;
  overflow: visible;
  align-items: center;

  &:focus {
    @include focus-outline('border');
  }

  @if $tooltip-type == 'definition' {
    cursor: default;
  }

  @if $tooltip-type == 'icon' {
    cursor: pointer;

    &:focus {
      outline: 1px solid transparent;

      svg {
        @include focus-outline('border');
      }
    }
  }

  // ::before - Tooltip caret
  // ::after - legacy Tooltip content (deprecated)
  // .#{$prefix}--assistive-text - WCAG 2.1 compliant tooltip content
  //    that can either be a child (icon tooltip) or sibling (definition tooltip)
  &::before,
  &::after,
  .#{$prefix}--assistive-text,
  + .#{$prefix}--assistive-text {
    position: absolute;
    z-index: z('floating');
    display: flex;
    align-items: center;
    opacity: 0;
    pointer-events: none;

    // IE media query
    @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
      display: inline-block;
    }
  }

  &::before,
  &::after {
    transition: opacity $duration-fast-01 motion(standard, productive);

    @media screen and (prefers-reduced-motion: reduce) {
      transition: none;
    }
  }

  &.#{$prefix}--tooltip--a11y::before,
  &.#{$prefix}--tooltip--a11y::after {
    transition: none;
  }

  // caret
  &::before {
    border-style: solid;
    block-size: 0;
    content: '';
    inline-size: 0;
  }

  .#{$prefix}--assistive-text,
  + .#{$prefix}--assistive-text {
    box-sizing: content-box;
    color: inherit;
    // In order to pass AAT, opacity must be set to 1 in the default state
    // On focus/hover use a keyframe animation to mimic transition
    opacity: 1;
    // overwrite default nowrap behavior
    white-space: normal;
    word-break: break-word;
  }

  // content box
  // TODO: Simplify CSS selectors on next major release
  &::after,
  .#{$prefix}--assistive-text,
  + .#{$prefix}--assistive-text {
    @include tooltip--content($tooltip-type);
  }

  &::after {
    content: attr(aria-label);
  }

  &.#{$prefix}--tooltip--a11y::after {
    content: none;
  }

  &.#{$prefix}--tooltip--visible,
  &:hover,
  &:focus {
    &::before,
    &::after {
      opacity: 1;
    }

    @keyframes #{$prefix}--tooltip-fade {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    .#{$prefix}--assistive-text,
    + .#{$prefix}--assistive-text {
      overflow: visible;
      margin: auto;
      clip: auto;
    }

    .#{$prefix}--assistive-text,
    + .#{$prefix}--assistive-text,
    &.#{$prefix}--tooltip--a11y::before {
      animation: #{$prefix}--tooltip-fade $duration-fast-01
        motion(standard, productive);
    }
  }

  &.#{$prefix}--tooltip--hidden .#{$prefix}--assistive-text,
  &.#{$prefix}--tooltip--hidden + .#{$prefix}--assistive-text {
    overflow: hidden;
    margin: -1px;
    clip: rect(0, 0, 0, 0);
  }

  &.#{$prefix}--tooltip--hidden.#{$prefix}--tooltip--a11y::before {
    animation: none;
    opacity: 0;
  }
}

// Tooltip
// Definition and Icon CSS only tooltip
/// @param {String} $tooltip-type ['icon'] - The type, from: `icon`, `definition`
/// @param {String} $position ['bottom'] - The position, from: `top`, `right`, `bottom`, `left`
/// @param {String} $align ['center'] - The alignment, from: `start`, `center`, `end`
/// @access public
/// @group tooltip
@mixin tooltip--placement(
  $tooltip-type: 'icon',
  $position: 'bottom',
  $align: 'center'
) {
  // position and alignment
  $caret-spacing: $spacing-03;

  @if $tooltip-type == 'definition' {
    $caret-spacing: $spacing-02;
  }

  // space between caret and trigger button
  $caret-height: convert.to-rem(5px);
  $caret-width: convert.to-rem(8px);
  $body-spacing: $caret-spacing + $caret-height;

  // Use pseudo element to create invisible hover area to keep tooltip open on hover
  .#{$prefix}--assistive-text::after {
    position: absolute;
    display: block;
    content: '';
    // clip-path: polygon(50% 100%, 0 0, 100% 0);

    @if ($position == 'top' or $position == 'bottom') {
      block-size: convert.to-rem(12px);
      inline-size: 100%;
      inset-inline-start: 0;
    }

    @if ($position == 'left' or $position == 'right') {
      block-size: 100%;
      inline-size: convert.to-rem(12px);
      inset-block-start: 0;
    }

    @if ($position == 'top') {
      inset-block-end: convert.to-rem(-12px);
    }
    @if ($position == 'right') {
      inset-inline-start: convert.to-rem(-12px);
    }
    @if ($position == 'bottom') {
      inset-block-start: convert.to-rem(-12px);
    }
    @if ($position == 'left') {
      inset-inline-end: convert.to-rem(-12px);
    }
  }

  // TODO: Simplify CSS selectors on next major release
  &::before,
  &::after,
  .#{$prefix}--assistive-text,
  + .#{$prefix}--assistive-text {
    @if ($position == 'top') {
      inset-block-start: 0;
      inset-inline-start: 50%;
    }
    @if ($position == 'right') {
      inset-block-start: 50%;
      inset-inline-end: 0;
    }
    @if ($position == 'bottom') {
      inset-block-end: 0;
      inset-inline-start: 50%;
    }
    @if ($position == 'left') {
      inset-block-start: 50%;
      inset-inline-start: 0;
    }
  }

  &::before {
    @if ($position == 'top') {
      border-width: convert.to-rem(5px)
        convert.to-rem(4px)
        0
        convert.to-rem(4px);
      border-color: $background-inverse transparent transparent transparent;
      inset-block-start: -$caret-spacing;
      transform: translate(-50%, -100%);
    }
    @if ($position == 'right') {
      border-width: convert.to-rem(4px)
        convert.to-rem(5px)
        convert.to-rem(4px)
        0;
      border-color: transparent $background-inverse transparent transparent;
      inset-inline-end: -$caret-spacing;
      transform: translate(100%, -50%);
    }
    @if ($position == 'bottom') {
      border-width: 0 convert.to-rem(4px) convert.to-rem(5px);
      border-color: transparent transparent $background-inverse;
      inset-block-end: -$caret-spacing;
      transform: translate(-50%, 100%);
    }
    @if ($position == 'left') {
      border-width: convert.to-rem(4px)
        0
        convert.to-rem(4px)
        convert.to-rem(5px);
      border-color: transparent transparent transparent $background-inverse;
      inset-inline-start: -$caret-spacing;
      transform: translate(-100%, -50%);
    }
  }

  // alignment options available only for top and bottom tooltip position
  // TODO: Simplify CSS selectors on next major release
  &::after,
  .#{$prefix}--assistive-text,
  + .#{$prefix}--assistive-text {
    @if ($position == 'top') {
      inset-block-start: -$body-spacing;
      @if ($align == 'start') {
        inset-inline-start: 0;
        transform: translate(0, -100%);
      } @else if ($align == 'end') {
        inset-inline: auto 0;
        transform: translate(0, -100%);
      } @else {
        inset-inline-start: 50%;
        transform: translate(-50%, -100%);
      }
    }
    @if ($position == 'right') {
      inset-inline-end: -$body-spacing;
      transform: translate(100%, -50%);
    }
    @if ($position == 'bottom') {
      inset-block-end: -$body-spacing;
      @if ($align == 'start') {
        inset-inline-start: 0;
        transform: translate(0, 100%);
      } @else if ($align == 'end') {
        inset-inline: auto 0;
        transform: translate(0, 100%);
      } @else {
        transform: translate(-50%, 100%);
      }
    }
    @if ($position == 'left') {
      inset-inline-start: -$body-spacing;
      transform: translate(-100%, -50%);
    }
  }

  // TODO: simplify on next major release to move the ::before pseudo element within the tooltip instead of the trigger
  @if $tooltip-type == 'definition' {
    &.#{$prefix}--tooltip--a11y + .#{$prefix}--assistive-text {
      @if ($position == 'bottom') {
        // carryover from https://github.com/carbon-design-system/carbon/pull/3151/files#diff-93734be0784e9530b6d14a7b03b0d352R261-R265
        inset-block-end: -($body-spacing - convert.to-rem(1px));
        @if ($align == 'start' or $align == 'end') {
          transform: translate(0, 100%);
        } @else {
          transform: translate(-50%, 100%);
        }
      }
    }
  }
}
