@use '../../theme/styles' as theme;

$toast-colors: (
  info: primary,
  success: success,
  warning: warning,
  danger: danger,
);

// Toast pane stays zero-sized so the CDK global wrapper around it doesn't
// swallow clicks on the rest of the page. The actual toast stack is rendered
// by `.wr-toast-host` below, which is `position: fixed` and therefore lays
// itself out against the viewport, not this pane.
.wr-toast-overlay {
  pointer-events: none;
}

.wr-toast-host {
  position: fixed;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  // Safe-area: fold each inset into the matching padding side so toasts clear
  // notches / the home indicator / rounded corners on mobile, whichever edge
  // the host is anchored to. env() is 0 without insets, so desktop stays 1rem.
  padding: calc(1rem + env(safe-area-inset-top)) calc(1rem + env(safe-area-inset-right))
    calc(1rem + env(safe-area-inset-bottom)) calc(1rem + env(safe-area-inset-left));
  pointer-events: none;
  max-width: 22rem;
  width: 100%;

  > * {
    pointer-events: auto;
  }

  // While expanded the toasts spread into a column with gaps. Those gaps are
  // dead space under `pointer-events: none`, so the cursor crossing them fires
  // mouseleave/mouseenter and toggles `expanded` (jitter). Make the whole host
  // hit-testable while expanded so the inter-toast gaps stay "inside" it.
  &--expanded {
    pointer-events: auto;
  }

  // Sonner-style stack
  // Collapsed: every toast except the front one collapses behind it with a
  // scale-down + tiny offset. Hovering the host expands them into the
  // normal vertical list.
  &--stack {
    // Anchor for absolute children when collapsed.
    position: fixed;
  }

  &--stack:not(.wr-toast-host--expanded) {
    .wr-toast {
      --wr-toast-i: var(--wr-toast-stack-index, 0);
      position: absolute;
      left: 1rem;
      right: 1rem;
      width: auto;
      max-width: calc(100% - 2rem);
      transition:
        transform 240ms cubic-bezier(0.4, 0, 0.2, 1),
        opacity 240ms ease,
        box-shadow 240ms ease;
      transform-origin: center top;
      transform: translateY(calc(var(--wr-toast-i) * 8px)) scale(calc(1 - var(--wr-toast-i) * 0.05));
      opacity: calc(1 - var(--wr-toast-i) * 0.3);
      z-index: calc(100 - var(--wr-toast-i));

      // Hide toasts more than 3 deep.
      &:where([style*='--wr-toast-stack-index: 3']),
      &:where([style*='--wr-toast-stack-index: 4']),
      &:where([style*='--wr-toast-stack-index: 5']) {
        opacity: 0;
        pointer-events: none;
      }
    }
  }

  // Bottom-anchored hosts: stack grows UPWARD (newest at the bottom).
  &--stack:not(.wr-toast-host--expanded).wr-toast-host--bottom,
  &--stack:not(.wr-toast-host--expanded).wr-toast-host--bottom-start,
  &--stack:not(.wr-toast-host--expanded).wr-toast-host--bottom-end {
    .wr-toast {
      transform-origin: center bottom;
      transform: translateY(calc(var(--wr-toast-i) * -8px)) scale(calc(1 - var(--wr-toast-i) * 0.05));
    }
  }

  &--stack.wr-toast-host--expanded .wr-toast {
    transition:
      transform 240ms cubic-bezier(0.4, 0, 0.2, 1),
      opacity 240ms ease;
  }

  &--top {
    top: 0;
    left: 50%;
    transform: translateX(-50%);
  }
  &--top-start {
    top: 0;
    left: 0;
  }
  &--top-end {
    top: 0;
    right: 0;
  }
  &--bottom {
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    flex-direction: column-reverse;
  }
  &--bottom-start {
    bottom: 0;
    left: 0;
    flex-direction: column-reverse;
  }
  &--bottom-end {
    bottom: 0;
    right: 0;
    flex-direction: column-reverse;
  }
}

.wr-toast {
  --wr-toast-bg: var(--wr-color-white);
  --wr-toast-border: var(--wr-color-light);
  --wr-toast-accent: var(--wr-color-primary);
  --wr-toast-title: var(--wr-color-dark);
  --wr-toast-message: var(--wr-color-medium);

  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 0.875rem;
  background: var(--wr-toast-bg);
  border: 1px solid var(--wr-toast-border);
  // Capture horizontal swipe-to-dismiss; let vertical scroll pass through.
  touch-action: pan-y;
  border-left: 3px solid var(--wr-toast-accent);
  @include theme.smooth-br(var(--wr-border-radius-base));
  box-shadow: var(--wr-shadow-overlay);
  font-family: var(--wr-font-family-base);
  animation: wr-toast-in 0.18s ease-out;
  overflow: hidden;

  &__body {
    flex: 1 1 auto;
    min-width: 0;
  }

  &__title {
    margin: 0 0 0.125rem;
    color: var(--wr-toast-title);
    font-size: var(--wr-text-sm);
    font-weight: 600;
    line-height: 1.25rem;
  }

  &__message {
    margin: 0;
    color: var(--wr-toast-message);
    font-size: var(--wr-text-sm);
    line-height: 1.125rem;
    overflow-wrap: break-word;
  }

  &__actions {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
  }

  &__action {
    appearance: none;
    background: transparent;
    border: 0;
    padding: 0.125rem;
    color: var(--wr-color-medium);
    cursor: pointer;
    border-radius: var(--wr-border-radius-sm);
    transition:
      color var(--wr-transition-base),
      background var(--wr-transition-base);

    --wr-icon-size: 0.875rem;

    &:hover {
      color: var(--wr-color-dark);
      background: var(--wr-color-hover);
    }
  }

  &__progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 2px;
    width: 100%;
    transform-origin: left;
    background: var(--wr-toast-accent);
    animation: wr-toast-progress linear forwards;
    animation-duration: var(--wr-toast-duration, 4000ms);
  }

  &:hover &__progress {
    animation-play-state: paused;
  }

  @each $variant, $color in $toast-colors {
    &--#{$variant} {
      --wr-toast-accent: var(--wr-color-#{$color});
    }
  }
}

@keyframes wr-toast-in {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes wr-toast-progress {
  from {
    transform: scaleX(1);
  }
  to {
    transform: scaleX(0);
  }
}

.wr-toast-host__close-all {
  // Full bleed to match toast width so the cursor never leaves a hit
  // region between toasts and button (was a source of expand/collapse
  // flicker in stack mode).
  align-self: stretch;
  pointer-events: auto;
  appearance: none;
  background: var(--wr-color-white);
  border: 1px solid var(--wr-color-light);
  @include theme.smooth-br(var(--wr-border-radius-base));
  padding: 0.375rem 0.75rem;
  color: var(--wr-color-medium);
  font-family: var(--wr-font-family-base);
  font-size: var(--wr-text-xs);
  font-weight: 500;
  line-height: 1rem;
  text-align: center;
  cursor: pointer;
  box-shadow: var(--wr-shadow-xs);
  transition:
    color var(--wr-transition-base),
    background var(--wr-transition-base),
    border-color var(--wr-transition-base);

  &:hover {
    color: var(--wr-color-dark);
    border-color: var(--wr-color-medium);
  }
}

// Bottom positions reverse so the close-all sits *above* the newest toast.
.wr-toast-host--bottom .wr-toast-host__close-all,
.wr-toast-host--bottom-start .wr-toast-host__close-all,
.wr-toast-host--bottom-end .wr-toast-host__close-all {
  order: 99;
  align-self: stretch;
}

// Touch pointers: grow the per-toast action buttons (copy / dismiss) to ~32px
// with a wider gap so the pair no longer sits 2px apart, and give the
// dismiss-all bar a taller hit area. Fine pointers keep the compact desktop
// sizing above.
@media (pointer: coarse) {
  .wr-toast__actions {
    gap: 0.25rem;
  }

  .wr-toast__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    --wr-icon-size: 1.125rem;
  }

  .wr-toast-host__close-all {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
  }
}
