//
// Copyright IBM Corp. 2016, 2023
//
// 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 'mixins' as *;
@use '../copy-button';
@use '../../config' as *;
@use '../../motion' as *;
@use '../../spacing' as *;
@use '../../theme' as *;
@use '../../type' as *;
@use '../../layer' as *;
@use '../../utilities/convert';
@use '../../utilities/focus-outline' as *;
@use '../../utilities/high-contrast-mode' as *;
@use '../../utilities/keyframes' as *;
@use '../../utilities/layout' as *;
@use '../../utilities/skeleton' as *;
@use '../../utilities/tooltip' as *;
@use '../../utilities/z-index' as *;

/// @type Color
/// @access public
/// @group copy-button
$copy-active: $layer-active !default;

/// @type Color
/// @access public
/// @group copy-button
$copy-btn-feedback: $background-inverse !default;

@mixin code-snippet {
  .#{$prefix}--snippet {
    @include reset;
  }

  .#{$prefix}--snippet--disabled,
  .#{$prefix}--snippet--disabled
    .#{$prefix}--btn.#{$prefix}--snippet-btn--expand {
    background-color: $layer;
    color: $text-disabled;
  }

  .#{$prefix}--snippet--disabled .#{$prefix}--snippet-btn--expand:hover,
  .#{$prefix}--snippet--disabled .#{$prefix}--copy-btn,
  .#{$prefix}--snippet--disabled .#{$prefix}--copy-btn:hover {
    background-color: $layer;
    color: $text-disabled;
    cursor: not-allowed;
  }

  .#{$prefix}--snippet--disabled .#{$prefix}--snippet__icon,
  .#{$prefix}--snippet--disabled
    .#{$prefix}--snippet-btn--expand
    .#{$prefix}--icon-chevron--down {
    fill: $icon-disabled;
  }

  .#{$prefix}--snippet code {
    @include type-style('code-01');
  }

  // Inline Code Snippet
  .#{$prefix}--snippet--inline {
    @include reset;

    position: relative;
    display: inline;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 4px;
    background-color: $layer;
    color: $text-primary;
    cursor: pointer;

    &:hover {
      background-color: $layer-hover;
    }

    &:active {
      background-color: $layer-active;
    }

    &:focus {
      border: 1px solid $focus;
      outline: none;
    }

    &::before {
      @include tooltip--caret;

      display: none;

      border: none;
    }

    .#{$prefix}--copy-btn__feedback {
      @include tooltip--content('icon');

      display: none;
      overflow: visible;
      box-sizing: content-box;
      margin: auto;
      clip: auto;
    }
  }

  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating::before,
  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating
    .#{$prefix}--copy-btn__feedback {
    display: block;
  }

  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out::before,
  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out
    .#{$prefix}--copy-btn__feedback {
    animation: $duration-fast-02 motion(standard, productive) #{$prefix}--hide-feedback;
  }

  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in::before,
  .#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in
    .#{$prefix}--copy-btn__feedback {
    animation: $duration-fast-02 motion(standard, productive) #{$prefix}--show-feedback;
  }

  .#{$prefix}--snippet--inline code {
    padding: 0 $spacing-03;
  }

  .#{$prefix}--snippet--inline.#{$prefix}--snippet--no-copy {
    display: inline-block;

    &:hover {
      background-color: $layer;
      cursor: auto;
    }
  }

  .#{$prefix}--snippet--light.#{$prefix}--snippet--inline.#{$prefix}--snippet--no-copy:hover {
    background-color: $layer-hover;
    cursor: auto;
  }

  // Single Line Snippet
  .#{$prefix}--snippet--single {
    @include bx--snippet;

    display: flex;
    align-items: center;
    block-size: $spacing-08;
    padding-inline-end: $spacing-08;
  }

  .#{$prefix}--snippet--single.#{$prefix}--snippet--no-copy {
    padding: 0;

    &::after {
      inset-inline-end: $spacing-05;
    }
  }

  .#{$prefix}--snippet--single .#{$prefix}--snippet-container {
    position: relative;
    display: flex;
    align-items: center;
    block-size: 100%;
    overflow-x: auto;
    padding-inline-start: $spacing-05;

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

  .#{$prefix}--snippet--single pre {
    @include type-style('code-01');

    padding-inline-end: $spacing-07;
  }

  // Preserve whitespace, but don't allow wrapping for inline and single
  .#{$prefix}--snippet--single pre,
  .#{$prefix}--snippet--inline code {
    white-space: pre;
  }

  // Multi Line Snippet
  .#{$prefix}--snippet--multi {
    @include bx--snippet;

    display: flex;
    padding: $spacing-05;
  }

  //collapsed snippet container
  .#{$prefix}--snippet--multi .#{$prefix}--snippet-container {
    position: relative;
    order: 1;
    max-block-size: 100%;
    min-block-size: 100%;
    overflow-y: auto;
    transition: max-height $duration-moderate-01 motion(standard, productive);

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

      outline-offset: 0;
    }
  }

  // expanded snippet container
  .#{$prefix}--snippet--multi.#{$prefix}--snippet--expand
    .#{$prefix}--snippet-container {
    padding-block-end: $spacing-05;
    transition: max-height $duration-moderate-01 motion(standard, productive);
  }

  .#{$prefix}--snippet--multi.#{$prefix}--snippet--wraptext pre {
    white-space: pre-wrap;
    word-wrap: break-word;
  }

  .#{$prefix}--snippet--multi .#{$prefix}--snippet-container pre {
    overflow: auto;
    padding-block-end: $spacing-06;
    padding-inline-end: $spacing-06;
  }

  .#{$prefix}--snippet--multi.#{$prefix}--snippet--no-copy
    .#{$prefix}--snippet-container
    pre {
    padding-inline-end: 0;
  }

  [dir='rtl']
    .#{$prefix}--snippet--multi.#{$prefix}--snippet--has-right-overflow::after {
    background-image: linear-gradient(to left, transparent, $layer);
  }

  .#{$prefix}--snippet--multi .#{$prefix}--snippet-container pre code {
    overflow: hidden;
  }

  //Copy Button
  .#{$prefix}--snippet__icon {
    block-size: convert.to-rem(16px);
    fill: $icon-primary;
    inline-size: convert.to-rem(16px);
    transition: all $duration-fast-01 motion(standard, productive);
  }

  .#{$prefix}--btn > .#{$prefix}--snippet__icon {
    margin-block-start: 0;
  }

  .#{$prefix}--copy-btn {
    @include reset;

    display: flex;
    overflow: visible;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background-color: $layer;
    cursor: pointer;
    outline: none;

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

      outline-color: $focus;
    }
  }

  // TODO: remove copy button styles above
  .#{$prefix}--snippet .#{$prefix}--popover-container {
    @include font-family('sans');

    position: absolute;
    inset-block-start: 0;
    inset-inline-end: 0;
  }

  // Overrides for codesnippet copy btn
  // TLDR: Copy/CopyButton now uses IconButton, which uses Carbon buttons under the hood
  // v10 Copy just used native html button so it didn't have extra carbon styles that needed overriding
  .#{$prefix}--snippet--inline.#{$prefix}--btn {
    block-size: 1.25rem;
    inline-size: initial;
    max-inline-size: unset;
    min-block-size: 1.25rem;
    padding-inline: 0;
  }

  .#{$prefix}--snippet--inline.#{$prefix}--btn.#{$prefix}--btn--primary:hover {
    color: $text-primary;
  }

  // override multi copy btn styles
  .#{$prefix}--snippet.#{$prefix}--snippet--multi
    .#{$prefix}--popover-container {
    inset-block-start: 0.5rem;
    inset-inline-end: 0.5rem;
  }

  .#{$prefix}--snippet--multi .#{$prefix}--copy-btn {
    z-index: 10;
  }

  // Show more / less button
  .#{$prefix}--snippet-btn--expand {
    @include type-style('body-compact-01');
    @include font-family('sans');

    position: absolute;
    z-index: 10;
    display: inline-flex;
    align-items: center;

    padding: $spacing-03 $spacing-05;
    border: 0;
    background-color: $layer;
    block-size: convert.to-rem(32px);
    color: $text-primary;
    inset-block-end: 0;
    inset-inline-end: 0;
  }

  .#{$prefix}--snippet-btn--expand .#{$prefix}--snippet-btn--text {
    position: relative;
    inset-block-start: convert.to-rem(-1px);
  }

  .#{$prefix}--snippet-btn--expand--hide.#{$prefix}--snippet-btn--expand {
    display: none;
  }

  .#{$prefix}--snippet-btn--expand .#{$prefix}--icon-chevron--down {
    fill: $icon-primary;
    margin-inline-start: $spacing-03;
    transform: rotate(0deg);
    transition: $duration-moderate-01 motion(standard, productive);
  }

  .#{$prefix}--snippet-btn--expand:hover {
    background: $layer-hover;
    color: $text-primary;
  }

  .#{$prefix}--snippet-btn--expand:active {
    background-color: $layer-active;
  }

  .#{$prefix}--snippet-btn--expand:focus {
    @include focus-outline('outline');

    border-color: transparent;
  }

  .#{$prefix}--snippet--expand
    .#{$prefix}--snippet-btn--expand
    .#{$prefix}--icon-chevron--down {
    transform: rotate(180deg);
    transition: transform $transition-expansion;
  }

  // Light version
  .#{$prefix}--snippet--light,
  .#{$prefix}--snippet--light .#{$prefix}--snippet-button,
  .#{$prefix}--snippet--light .#{$prefix}--btn.#{$prefix}--snippet-btn--expand,
  .#{$prefix}--snippet--light .#{$prefix}--copy-btn {
    background-color: $layer;
  }

  .#{$prefix}--snippet--light.#{$prefix}--snippet--inline:hover,
  .#{$prefix}--snippet--light .#{$prefix}--snippet-button:hover,
  .#{$prefix}--snippet--light
    .#{$prefix}--btn.#{$prefix}--snippet-btn--expand:hover,
  .#{$prefix}--snippet--light .#{$prefix}--copy-btn:hover {
    background-color: $layer-hover;
  }

  .#{$prefix}--snippet--light.#{$prefix}--snippet--inline:active,
  .#{$prefix}--snippet--light .#{$prefix}--snippet-button:active,
  .#{$prefix}--snippet--light
    .#{$prefix}--btn.#{$prefix}--snippet-btn--expand:active,
  .#{$prefix}--snippet--light .#{$prefix}--copy-btn:active {
    background-color: $layer-active;
  }

  // Skeleton State
  .#{$prefix}--snippet.#{$prefix}--skeleton .#{$prefix}--snippet-container {
    block-size: 100%;
    inline-size: 100%;
  }

  .#{$prefix}--snippet-button .#{$prefix}--btn--copy__feedback {
    // (The height of button) + (The height of the tooltip's triangle) + 4px
    inset-block-start: convert.to-rem(50.8px);
    inset-inline: 50% auto;

    &::before {
      inset-block-start: 0;
    }

    &::after {
      inset-block-start: convert.to-rem(-4px);
    }
  }

  .#{$prefix}--snippet--multi
    .#{$prefix}--snippet-button
    .#{$prefix}--btn--copy__feedback {
    // (The height of button) + (The height of the tooltip's triangle) + 4px
    inset-block-start: convert.to-rem(42.8px);
  }

  .#{$prefix}--snippet--inline .#{$prefix}--btn--copy__feedback {
    // TODO: use updated global tooltip mixins under the hood
    // since all of the positioning values for the copy button tooltip are arbitrary hard coded rem values, we need this arbitrary 4px offset to keep the proper tooltip spacing according to the spec
    inset-block-start: calc(100% - #{convert.to-rem(4px)});
    inset-inline: 50% auto;
  }

  // Using mask-image for single line snippet
  .#{$prefix}--snippet--single .#{$prefix}--snippet-container {
    mask-image: linear-gradient(
      to right,
      #000000 calc(100% - #{$spacing-07}),
      transparent 100%
    );
    pointer-events: auto;
  }

  .#{$prefix}--snippet--multi {
    position: relative;
  }

  .#{$prefix}--snippet--multi .#{$prefix}--snippet-container {
    inline-size: 100%;
    mask-composite: intersect;
    mask-image: linear-gradient(
        to right,
        #000000 calc(100% - #{$spacing-07}),
        transparent 100%
      ),
      linear-gradient(
        to bottom,
        #000000 calc(100% - #{$spacing-05}),
        transparent 100%
      );
    pointer-events: auto;
  }

  [dir='rtl'] .#{$prefix}--snippet--single .#{$prefix}--snippet-container {
    mask-image: linear-gradient(
      to left,
      #000000 calc(100% - #{$spacing-07}),
      transparent 100%
    );
  }

  [dir='rtl'] .#{$prefix}--snippet--multi .#{$prefix}--snippet-container {
    mask-image: linear-gradient(
        to left,
        #000000 calc(100% - #{$spacing-07}),
        transparent 100%
      ),
      linear-gradient(
        to bottom,
        #000000 calc(100% - #{$spacing-05}),
        transparent 100%
      );
  }

  .#{$prefix}--snippet--single:focus-within .#{$prefix}--snippet-container,
  .#{$prefix}--snippet--multi:focus-within .#{$prefix}--snippet-container {
    mask-image: none;
  }

  .#{$prefix}--snippet--multi.#{$prefix}--skeleton {
    block-size: convert.to-rem(98px);
  }

  .#{$prefix}--snippet--single.#{$prefix}--skeleton {
    block-size: convert.to-rem(56px);
  }

  .#{$prefix}--snippet.#{$prefix}--skeleton span {
    @include skeleton;

    display: block;
    block-size: 1rem;
    inline-size: 100%;
    margin-block-start: 0.5rem;

    &:first-child {
      margin: 0;
    }

    &:nth-child(2) {
      inline-size: 85%;
    }

    &:nth-child(3) {
      inline-size: 95%;
    }
  }

  .#{$prefix}--snippet--single.#{$prefix}--skeleton
    .#{$prefix}--snippet-container {
    padding-block-end: 0;
  }

  // Windows HCM fix
  .#{$prefix}--snippet--inline:focus {
    @include high-contrast-mode('focus');
  }

  .#{$prefix}--snippet--single,
  .#{$prefix}--snippet--multi {
    @include high-contrast-mode('outline');
  }
}
