//
// Copyright IBM Corp. 2014, 2026
//
// 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 'sass:list';
@use '../button';
@use '../../config' as *;
@use '../../feature-flags' as *;
@use '../../breakpoint' as *;
@use '../../motion' as *;
@use '../../spacing' as *;
@use '../../theme' as *;
@use '../../type' as *;
@use '../../utilities/ai-gradient' as *;
@use '../../utilities/convert';
@use '../../utilities/component-reset';
@use '../../utilities/focus-outline' as *;

/// Dialog styles
/// @access public
/// @group dialog
@mixin dialog($enable-presence: false) {
  .#{$prefix}--dialog {
    position: fixed;
    padding: 0;
    border: none;
    margin: auto;
    background-color: $layer;
    color: $text-primary;
    inline-size: 48rem;
    inset: 0;
    max-block-size: 100%;

    @include breakpoint(md) {
      max-inline-size: 84%;
    }
    @include breakpoint(lg) {
      max-inline-size: 60%;
    }
    @include breakpoint(xlg) {
      max-inline-size: 48%;
    }

    @if not(enabled('enable-presence') or $enable-presence) {
      opacity: 0;
      transform: translateY(calc(-1 * #{$spacing-06}));
      /** opening and closing is used in as allow-discrete is not currently supported wide enough
       * https://caniuse.com/mdn-css_properties_display_is_transitionable
       */
      transition:
        opacity $duration-moderate-02 motion(exit, expressive),
        transform $duration-moderate-02 motion(exit, expressive),
        overlay $duration-moderate-02 motion(exit, expressive) allow-discrete,
        display $duration-moderate-02 motion(exit, expressive) allow-discrete;

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

      &[open] {
        opacity: 1;
        transform: translateY(0);

        transition:
          opacity $duration-moderate-02 motion(entrance, expressive),
          transform $duration-moderate-02 motion(entrance, expressive),
          overlay
            $duration-moderate-02
            motion(entrance, expressive)
            allow-discrete,
          display
            $duration-moderate-02
            motion(entrance, expressive)
            allow-discrete;

        @media (prefers-reduced-motion) {
          transition: none;
        }
      }
    } @else {
      animation: #{$prefix}--presence-dialog__enter
        $duration-moderate-02
        motion(entrance, expressive)
        forwards;

      @media (prefers-reduced-motion) {
        animation: none;
      }

      &[data-exiting] {
        animation: #{$prefix}--presence-dialog__exit
          $duration-moderate-02
          motion(exit, expressive)
          forwards;

        @media (prefers-reduced-motion) {
          animation: none;
        }
      }

      @keyframes #{$prefix}--presence-dialog__enter {
        from {
          opacity: 0;
          transform: translateY(calc(-1 * #{$spacing-06}));
        }

        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      @keyframes #{$prefix}--presence-dialog__exit {
        from {
          opacity: 1;
          transform: translateY(0);
        }

        to {
          opacity: 0;
          transform: translateY(calc(-1 * #{$spacing-06}));
        }
      }
    }

    /** starting style also not supported widely
    * https://caniuse.com/mdn-css_at-rules_starting-style
    */
    /*   Before-open state  */
    /* Needs to be after the previous dialog[open] rule to take effect,
    as the specificity is the same */

    @starting-style {
      &[open] {
        opacity: 0;
        transform: translateY(calc(-1 * #{$spacing-06}));
      }
    }
  }

  .#{$prefix}--dialog__header {
    position: relative;
    grid-area: header;
    inline-size: 100%;
    margin-block-end: $spacing-03;
    min-block-size: $spacing-09;
    padding-block-start: $spacing-05;
    padding-inline: $spacing-05 $spacing-09;
  }

  .#{$prefix}--dialog::backdrop {
    background-color: $overlay;
    opacity: 0;
  }

  @if not(enabled('enable-presence') or $enable-presence) {
    /* Transition the :backdrop when the dialog modal is promoted to the top layer */
    .#{$prefix}--dialog::backdrop {
      /* opening and closing is used in as allow-discrete is not currently supported wide enough
       * https://caniuse.com/mdn-css_properties_display_is_transitionable
       */
      transition:
        background-color $duration-moderate-02 motion(entrance, expressive),
        opacity $duration-moderate-02 motion(entrance, expressive);

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

    .#{$prefix}--dialog[open]::backdrop {
      opacity: 1;
      transition:
        background-color $duration-moderate-02 motion(exit, expressive),
        opacity $duration-moderate-02 motion(exit, expressive);

      @media (prefers-reduced-motion) {
        transition: none;
      }
    }
  } @else {
    .#{$prefix}--dialog {
      &::backdrop {
        animation: #{$prefix}--presence-dialog-backdrop__enter
          $duration-moderate-02
          motion(entrance, expressive)
          forwards;

        @media (prefers-reduced-motion) {
          animation: none;
        }
      }

      &[data-exiting]::backdrop {
        animation: #{$prefix}--presence-dialog-backdrop__exit
          $duration-moderate-02
          motion(exit, expressive)
          forwards;

        @media (prefers-reduced-motion) {
          animation: none;
        }
      }
    }

    @keyframes #{$prefix}--presence-dialog-backdrop__enter {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    @keyframes #{$prefix}--presence-dialog-backdrop__exit {
      from {
        opacity: 1;
      }

      to {
        opacity: 0;
      }
    }
  }

  /** starting style also not supported widely
  * https://caniuse.com/mdn-css_at-rules_starting-style
  */
  /* This starting-style rule cannot be nested inside the above selector
  because the nesting selector cannot represent pseudo-elements. */

  @starting-style {
    .#{$prefix}--dialog[open]::backdrop {
      opacity: 0;
    }
  }

  .#{$prefix}--dialog__header-controls {
    position: absolute;
    inset-block-start: 0;
    inset-inline-end: 0;
  }

  .#{$prefix}--dialog-header__label {
    @include component-reset.reset;

    @include type-style('label-01');

    color: $text-secondary;
    margin-block-end: $spacing-02;
  }

  .#{$prefix}--dialog-header__heading {
    @include component-reset.reset;

    @include type-style('heading-03');

    margin: 0;
    color: $text-primary;

    padding-inline-end: calc(20% - $spacing-09);
  }

  .#{$prefix}--dialog-container {
    display: grid;
    box-sizing: border-box;
    border: 1px solid $border-subtle-01;
    background-color: $layer;
    grid-template-areas:
      'header'
      'content'
      'footer';
    grid-template-columns: 100%;
    grid-template-rows: auto minmax(0, 1fr) auto;
    inline-size: 100%;

    @include breakpoint(md) {
      max-block-size: 90vh;
    }

    @include breakpoint(lg) {
      max-block-size: 84vh;
    }
  }

  .#{$prefix}--dialog-content {
    position: relative;
    grid-area: content;
    overflow-y: auto;
    padding-block: $spacing-03 $spacing-09;
    padding-inline: $spacing-05 $spacing-05;

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

  .#{$prefix}--dialog-scroll-content {
    border-block-end: $spacing-01 solid transparent;
    mask-image: linear-gradient(
        to bottom,
        $layer calc(100% - $spacing-11),
        transparent calc(100% - $spacing-09),
        transparent 100%
      ),
      linear-gradient(to left, $layer 0, $spacing-05, transparent $spacing-05),
      linear-gradient(to right, $layer 0, $spacing-01, transparent $spacing-01),
      linear-gradient(to top, $layer 0, $spacing-01, transparent $spacing-01);
  }

  .#{$prefix}--dialog-scroll-content > *:last-child {
    margin-block-end: $spacing-06;
  }

  .#{$prefix}--dialog-scroll-content:has(.#{$prefix}--autoalign) {
    mask-image: none;
  }

  .#{$prefix}--dialog-scroll-content.#{$prefix}--dialog-scroll-content--no-fade,
  .#{$prefix}--dialog-scroll-content--no-fade {
    mask-image: none;
  }

  .#{$prefix}--dialog-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    block-size: $spacing-10;
    grid-area: footer;
  }

  .#{$prefix}--dialog-footer .#{$prefix}--btn {
    flex: 0 1 50%;
    align-items: baseline;
    margin: 0;
    block-size: $spacing-10;
    max-inline-size: none;
  }

  .#{$prefix}--dialog-footer--three-button .#{$prefix}--btn {
    flex: 0 1 25%;
    align-items: flex-start;
  }

  .#{$prefix}--dialog--danger {
    background-color: $ai-overlay;
  }

  .#{$prefix}--dialog--danger .#{$prefix}--dialog-container {
    @include ai-popover-gradient('default', 0, 'layer');

    border: 1px solid transparent;
    background-color: $layer;
    box-shadow:
      inset 0 -80px 70px -65px $ai-inner-shadow,
      0 24px 40px -24px $ai-drop-shadow;
  }

  .#{$prefix}--dialog--danger
    .#{$prefix}--dialog-container:has(.#{$prefix}--dialog-footer) {
    @include ai-popover-gradient('default', $spacing-10, 'layer');

    box-shadow:
      inset 0 -80px 0 -16px $layer,
      inset 0 -160px 70px -65px $ai-inner-shadow,
      0 24px 40px -24px $ai-drop-shadow;
  }

  .#{$prefix}--dialog--danger
    .#{$prefix}--dialog-content.#{$prefix}--dialog-scroll-content {
    mask-image: linear-gradient(
        to bottom,
        $layer calc(100% - $spacing-11),
        transparent calc(100% - $spacing-09),
        transparent 100%
      ),
      linear-gradient(to left, $layer 0, $spacing-05, transparent $spacing-05),
      linear-gradient(to right, $layer 0, $spacing-01, transparent $spacing-01),
      linear-gradient(to top, $layer 0, $spacing-01, transparent $spacing-01);
  }
  .#{$prefix}--dialog__close {
    padding: convert.to-rem(12px);
    border: 2px solid transparent;
    background-color: transparent;
    block-size: 3rem;
    cursor: pointer;
    inline-size: 3rem;
    transition: background-color $duration-fast-02 motion(standard, productive);

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

    &:focus {
      border-color: $focus;
      outline: none;
    }
  }
}
