//
// Copyright 2022 Google LLC
// SPDX-License-Identifier: Apache-2.0
//

// go/keep-sorted start
@use 'sass:map';
// go/keep-sorted end
// go/keep-sorted start
@use '../../elevation/elevation';
@use '../../focus/focus-ring';
@use '../../ripple/ripple';
@use '../../tokens';
@use './fab';
// go/keep-sorted end

$_md-sys-motion: tokens.md-sys-motion-values();

@mixin styles() {
  :host {
    @include ripple.theme(
      (
        hover-opacity: var(--_hover-state-layer-opacity),
        pressed-opacity: var(--_pressed-state-layer-opacity),
      )
    );

    display: inline-flex;
  }

  :host([size='medium'][touch-target='wrapper']) {
    margin: max(0px, 48px - var(--_container-height));
  }

  :host([size='large'][touch-target='wrapper']) {
    margin: max(0px, 48px - var(--_large-container-height));
  }

  .fab,
  .icon,
  .icon ::slotted(*) {
    display: flex;
  }

  .fab {
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    padding: 0;
    position: relative;
    height: var(--_container-height);
    transition-property: background-color;
    border-width: 0px;
    outline: none;
    // Required for elevation and ripple to stay below content
    z-index: 0;

    &.extended {
      width: inherit;
      box-sizing: border-box;
      padding-inline-start: 16px;
      padding-inline-end: 20px;
    }

    &:not(.extended) {
      width: var(--_container-width);
    }

    &.large {
      width: var(--_large-container-width);
      height: var(--_large-container-height);

      .icon ::slotted(*) {
        width: var(--_large-icon-size);
        height: var(--_large-icon-size);
        font-size: var(--_large-icon-size);
      }

      &,
      .ripple {
        border-start-start-radius: var(--_large-container-shape-start-start);
        border-start-end-radius: var(--_large-container-shape-start-end);
        border-end-start-radius: var(--_large-container-shape-end-start);
        border-end-end-radius: var(--_large-container-shape-end-end);
      }

      md-focus-ring {
        @include focus-ring.theme(
          (
            'shape-start-start': var(--_large-container-shape-start-start),
            'shape-start-end': var(--_large-container-shape-start-end),
            'shape-end-end': var(--_large-container-shape-end-end),
            'shape-end-start': var(--_large-container-shape-end-start),
          )
        );
      }
    }

    @include _elevation(
      (
        'default': var(--_container-elevation),
        'focus': var(--_focus-container-elevation),
        'hover': var(--_hover-container-elevation),
        'pressed': var(--_pressed-container-elevation),
      ),
      var(--_container-shadow-color)
    );

    &.lowered {
      background-color: var(--_lowered-container-color);

      @include _elevation(
        (
          'default': var(--_lowered-container-elevation),
          'focus': var(--_lowered-focus-container-elevation),
          'hover': var(--_lowered-hover-container-elevation),
          'pressed': var(--_lowered-pressed-container-elevation),
        )
      );
    }

    @include fab.color(
      (
        'container-color': var(--_container-color),
        'hover-state-layer-color': var(--_hover-state-layer-color),
        'pressed-state-layer-color': var(--_pressed-state-layer-color),
        'label-text-color': var(--_label-text-color),
        'hover-label-text-color': var(--_hover-label-text-color),
        'focus-label-text-color': var(--_focus-label-text-color),
        'pressed-label-text-color': var(--_pressed-label-text-color),
      )
    );
  }

  .label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--_label-text-font);
    font-size: var(--_label-text-size);
    line-height: var(--_label-text-line-height);
    font-weight: var(--_label-text-weight);
  }

  .fab.extended .icon ::slotted(*) {
    margin-inline-end: 12px;
  }

  .ripple {
    overflow: hidden;
  }

  .ripple,
  md-elevation {
    // puts both behind content
    z-index: -1;
  }

  .touch-target {
    position: absolute;
    top: 50%;
    height: 48px;
    left: 50%;
    width: 48px;
    transform: translate(-50%, -50%);
  }

  :host([touch-target='none']) .touch-target {
    display: none;
  }

  md-elevation,
  .fab {
    // TODO: replace duration with animation tokens
    transition-duration: 280ms;
    transition-timing-function: map.get($_md-sys-motion, 'easing-emphasized');
  }

  .fab,
  .ripple {
    border-start-start-radius: var(--_container-shape-start-start);
    border-start-end-radius: var(--_container-shape-start-end);
    border-end-start-radius: var(--_container-shape-end-start);
    border-end-end-radius: var(--_container-shape-end-end);
  }

  md-focus-ring {
    @include focus-ring.theme(
      (
        'shape-start-start': var(--_container-shape-start-start),
        'shape-start-end': var(--_container-shape-start-end),
        'shape-end-end': var(--_container-shape-end-end),
        'shape-end-start': var(--_container-shape-end-start),
      )
    );
  }

  .icon ::slotted(*) {
    width: var(--_icon-size);
    height: var(--_icon-size);
    font-size: var(--_icon-size);
  }
}

@mixin _elevation($states, $shadow-color: null) {
  @include elevation.theme(
    (
      'level': map.get($states, 'default'),
    )
  );

  @if $shadow-color {
    @include elevation.theme(
      (
        'shadow-color': $shadow-color,
      )
    );
  }

  // apply elevation in order of focused, hovered, pressed, disabled
  // this ensures a button will have hover elevation after being focused
  &:focus {
    @include elevation.theme(
      (
        'level': map.get($states, 'focus'),
      )
    );
  }

  &:hover {
    @include elevation.theme(
      (
        'level': map.get($states, 'hover'),
      )
    );
  }

  &:active {
    @include elevation.theme(
      (
        'level': map.get($states, 'pressed'),
      )
    );
  }
}
