@use 'sass:math';
@use 'sass:meta';
@use 'interaction-state.utilities';
@use '../utils';

// Put state layer above content layer as default.
// You can change move the content layer on top by declaring e.g.:
//    --content-layer-z-index: calc(#{layer.$state-layer-z-index} + 1);
// in a component that uses interaction state layer.
$_content-layer-z-index: utils.z('default');
$state-layer-z-index: $_content-layer-z-index + 1;
$_dark: utils.get-color('black');
$_light: utils.get-color('black-contrast');

/// Prepare state layer and content layer for interaction state changes.
/// Should be initialized before applying hover.
/// @param {*} $border-width [0] - Necessary for making the state layer cover border (if any) on parent element
@mixin initialize-layer($border-width: 0) {
  // Wrap declarations to avoid clashes with other mixins that have nested rules.
  // See: https://sass-lang.com/documentation/breaking-changes/mixed-decls/
  & {
    --state-layer-opacity: 0;
    --state-layer-background-color: #{$_dark};

    position: relative;
  }

  .content-layer {
    position: relative;
    z-index: var(--content-layer-z-index, $_content-layer-z-index);
  }

  .state-layer {
    position: absolute;

    // When we use negated value of border-width on parent for inset
    // then the hover effect (state layer) will also cover the border.
    // Otherwise the border will not be affected on hover.
    // We usually want the hover effect to also cover the border.
    inset: $border-width * -1;
    overflow: hidden;
    pointer-events: none;
    border-radius: inherit;
    z-index: $state-layer-z-index;

    &::before {
      transition: interaction-state.transition();
      content: '';
      position: absolute;
      pointer-events: none;
      inset: 0;
      border-radius: inherit;
      opacity: var(--state-layer-opacity, 0);
      background-color: var(--state-layer-background-color, $_dark);
    }
  }
}

@mixin apply-state($loudness: interaction-state.$default-loudness-hover, $make-lighter: false) {
  $loudness-percent: interaction-state.get-loudness($loudness);

  @if not(meta.type-of($loudness-percent) == number and math.unit($loudness-percent) == '%') {
    @error "$loudness-percent must be a percentage";
  }

  --state-layer-opacity: #{math.div($loudness-percent, 100%)};

  @if $make-lighter {
    --state-layer-background-color: #{$_light};
  } @else {
    --state-layer-background-color: #{$_dark};
  }
}

@mixin extend-content {
  .content-layer {
    @content;
  }
}
