@use 'sass:meta';
@use 'sass:string';
@use '../../functions/is-alias' as *;
@use '../../functions/is-angle' as *;
@use '../../functions/is-list' as *;
@use '../../functions/is-string' as *;
@use '../../functions/list-to-string' as *;

/// Uses clip path to change an element to the shape of an arrow.
///
/// @param {String} $direction [right] - The direction the arrow is
/// pointing. Accepted values are: `top`, `top-right`, `right`, `bottom-right`,
/// `bottom`, `bottom-left`, `left`, `top-left`, `forwards`, `backwards`, and
/// all valid aliases for these $direction values.
/// @param {Number} $size [null] - The size of the arrow. If
/// the $height property is not set explicitly, it is both height and width, if
/// $height is set explicitly, then this value sets only the width.
/// @param {Color | Mixed} $bg [#80f] - The color or background value.
/// @param {Number} $height [$size] - The height of the arrow.
///
/// @group Shapes
/// @require {function} is-alias
/// @require {function} is-angle
/// @require {function} is-list
/// @require {function} is-string
/// @require {function} list-to-string
///
/// @throw Invalid $direction value error.
@mixin arrow($direction: 'right', $size: null, $bg: #80f, $height: $size) {
  @if $direction and (is-string($direction) or is-list($direction)) {
    @if is-list($direction) {
      $direction: list-to-string($direction);
    }

    @if is-string($direction) {
      $direction: string.to-lower-case($direction);
    }

    @if is-alias('right', $direction) or is-alias('bottom right', $direction) {
      clip-path: polygon(
        0 20%,
        60% 20%,
        60% 0,
        100% 50%,
        60% 100%,
        60% 80%,
        0 80%
      );

      @if is-alias('bottom right', $direction) {
        transform: rotate(45deg);
      }
    } @else if is-alias('left', $direction) or is-alias('top left', $direction) {
      clip-path: polygon(
        40% 0,
        40% 20%,
        100% 20%,
        100% 80%,
        40% 80%,
        40% 100%,
        0 50%
      );

      @if is-alias('top left', $direction) {
        transform: rotate(45deg);
      }
    } @else if is-alias('top', $direction) or is-alias('top right', $direction) {
      clip-path: polygon(
        100% 50%,
        75% 50%,
        75% 100%,
        25% 100%,
        25% 50%,
        0 50%,
        50% 0
      );

      @if is-alias('top right', $direction) {
        transform: rotate(45deg);
      }
    } @else if
      is-alias('bottom', $direction) or
      is-alias('bottom left', $direction)
    {
      clip-path: polygon(
        75% 0,
        75% 50%,
        100% 50%,
        50% 100%,
        0 50%,
        25% 50%,
        25% 0
      );

      @if is-alias('bottom left', $direction) {
        transform: rotate(45deg);
      }
    } @else {
      @error 'Invalid $direction keyword of #{meta.inspect($direction)} for ' +
          'the [ arrow() ] mixin. To pass a valid $direction value, choose ' +
          'an angle or one of the following direction keywords: `top`, ' +
          '`top-right`, `right`, `bottom-right`, `bottom`, `bottom-left`, ' +
          '`left`, `top-left` ';
    }
  } @else if $direction and is-angle($direction) {
    clip-path: polygon(
      100% 50%,
      75% 50%,
      75% 100%,
      25% 100%,
      25% 50%,
      0 50%,
      50% 0
    );
    transform: rotate($direction);
  } @else {
    @error 'Invalid $direction value of #{meta.inspect($direction)} for the ' +
        '[ arrow() ] mixin. To pass a valid $direction value, choose an angle ' +
        'or one of the following direction keywords: `top`, `top-right`, ' +
        '`right`, `bottom-right`, `bottom`, `bottom-left`, `left`, `top-left` ';
  }

  @if $size {
    width: $size;
  }

  @if $height {
    height: $height;
  }

  @if $bg {
    background: $bg;
  }
}
