<template>
  <component
    :is="tag"
    :disabled="buttonDisabled"
    :autofocus="autofocus"
    :type="nativeType"
    :href="href"
    :target="target"
    :class="[
      type ? `tf-button--${type} wt-button--${type}` : '',
      buttonSize ? `tf-button--${buttonSize} wt-button--${buttonSize}` : '',
      {
        'is-disabled': buttonDisabled
      },
      icon ? `has-icon icon-${icon}` : '',
      { [`has-icon icon-spinner`] : loading },
      { 'no-padding': noPadding },
      { 'no-border': noBorder }
    ]"
    :style="colorStyle"
    class="tf-button wt-button"
    @mousedown="$emit('mousedown', $event)"
    @mouseover="hover = true"
    @mouseout="hover = false"
    @click="handleClick"
  >
    <!-- Prepend icons to text -->
    <template v-if="icon && prepend">
      <icon
        :class="{ 'is-rotating': loading }"
        :name="!loading ? icon : 'spinner'"
      />
    </template>
    <span
      v-if="$slots.default"
      class="button-text"
    >
      <slot />
    </span>
    <!-- Add loading icon when there is no prefixed/affixed icon -->
    <icon
      v-if="!icon && loading"
      class="icon-loading is-rotating"
      name="spinner"
    />
    <!-- Append icons to text -->
    <template v-if="icon && !prepend">
      <icon
        :class="{ 'is-rotating': loading }"
        :name="!loading ? icon : 'spinner'"
      />
    </template>
    <div
      v-if="type === 'table-sort'"
      :class="`table-sort table-sort-${direction} ${selected ? 'table-sort-selected' : ''}`"
    >
      <icon name="angle-up" />
      <icon name="angle-up" />
    </div>
  </component>
</template>
<script>
  export default {
    name: 'TfButton',
    inject: {
      elForm: {
        default: '',
      },
      elFormItem: {
        default: '',
      },
      $themePrimaryButtonColor: { default: () => null },
      $themeSecondaryButtonColor: { default: () => null },
    },
    props: {
      tag: {
        type: String,
        default: 'button',
      },
      href: {
        type: String,
        default: null,
      },
      target: {
        type: String,
        default: null,
      },
      type: {
        type: String,
        default: 'default',
      },
      size: {
        type: String,
        default: null,
      },
      icon: {
        type: String,
        default: '',
      },
      nativeType: {
        type: String,
        default: 'button',
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      loading: {
        type: Boolean,
        default: false,
      },
      noPadding: {
        type: Boolean,
        default: false,
      },
      noBorder: {
        type: Boolean,
        default: false,
      },
      noBranding: {
        type: Boolean,
        default: false,
      },
      autofocus: {
        type: Boolean,
        default: false,
      },
      selected: {
        type: Boolean,
        default: false,
      },
      direction: {
        type: String,
        default: 'asc',
      },
      svgHeight: {
        type: Number,
        default: () => 15,
      },
      svgWidth: {
        type: Number,
        default: () => 12,
      },
      prepend: {
        type: Boolean,
        default: false,
      },
    },
    data: () => ({
      hover: false,
    }),
    computed: {
      /**
       * Return color value as reactive value
       *
       * @returns {string}
       */
      themePrimaryButtonColor() {
        return this.$themePrimaryButtonColor ? this.$themePrimaryButtonColor() : null;
      },
      /**
       * Return color value as reactive value
       *
       * @returns {string}
       */
      themeSecondaryButtonColor() {
        return this.$themeSecondaryButtonColor ? this.$themeSecondaryButtonColor() : null;
      },
      /**
       * inline styles to match primaryColor
       *
       * @returns {object}
       */
      colorStyle() {
        const style = {};

        if (this.buttonDisabled || this.noBranding) {
          return style;
        }

        if (this.themePrimaryButtonColor) {
          if (this.type === 'primary') {
            if ([
              'text-icon',
              'text-icon-small',
              'text',
              'text-small',
              'icon-no-fill',
            ].includes(this.size)) {
              // all text button styles and default icon style (no-fill)
              style.color = this.themePrimaryButtonColor;

              if (
                !this.noBorder
                && !this.noPadding
                && this.size === 'icon-no-fill'
                && this.hover
              ) {
                style.borderColor = this.themePrimaryButtonColor;
              }
            } else {
              // default primary button (large, medium, icon)
              style.backgroundColor = this.themePrimaryButtonColor;
              style.borderColor = this.themePrimaryButtonColor;
            }
          }
        }

        if (this.themeSecondaryButtonColor) {
          if (this.type === 'secondary') {
            style.color = this.themeSecondaryButtonColor;
            style.borderColor = this.themeSecondaryButtonColor;
          }
        }

        return style;
      },
      /**
       * get formItemSize (from Element)
       *
       * @returns {string}
       */
      elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      /**
       * get button size and if size is the deprecated 'icon-small', convert to new 'icon-no-fill'
       *
       * @returns {string}
       */
      buttonSize() {
        const updatedSize = this.size === 'icon-small' ? 'icon-no-fill' : this.size;
        return updatedSize
          || this.elFormItemSize
          || (this.$ELEMENT || {}).size;
      },
      /**
       * Is button disabled
       *
       * @returns {boolean}
       */
      buttonDisabled() {
        const disabledForm = (this.elForm || {}).disabled;

        return this.disabled || disabledForm || this.loading;
      },
    },
    methods: {
      /**
       * Emit click
       *
       * @param {event} evt
       */
      handleClick(evt) {
        this.$emit('click', evt);
      },
    },
  };
</script>

<style lang="scss" scoped>
  @import 'src/assets/styles/variables';
  @import 'src/assets/styles/mixins';

  .tf-button,
  .wt-button {
    white-space: nowrap;
    -webkit-appearance: none;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    text-align: center;
    box-sizing: border-box;
    outline: 0;
    margin: 0;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    background-color: $tf-blue;
    border-color: $tf-blue;
    color: $tf-white;
    font-size: 16px;
    padding: 7px 14px;
    border-radius: 0;
    text-transform: none;
    border: 2px $tf-blue solid;
    display: inline-flex;
    align-items: center;
    font-weight: 600;
    line-height: 1;

    &:not(.is-disabled) {
      cursor: pointer;
    }

    // 2-12-21 RLH - styles added to span to stop button text/icon from jumping when clicked in IE
    .button-text,
    svg {
      transform: translate(0, 0);
    }
  }

  .tf-button + .tf-button,
  .wt-button + .wt-button {
    margin-left: 14px;
  }

  .tf-button.tf-button--icon-no-fill + .tf-button.tf-button--icon-no-fill,
  .wt-button.wt-button--icon-no-fill + .wt-button.wt-button--icon-no-fill {
    margin-left: 10px;
  }

  .tf-button--large,
  .wt-button--large {
    font-size: 18px;
    padding: 12px 18px;
    border-radius: 25px;
  }

  .tf-button--medium,
  .tf-button--small,
  .wt-button--medium,
  .wt-button--small {
    border-radius: 3px;
  }

  .tf-button--medium,
  .wt-button--medium {
    font-size: 16px;
    padding: 7px 18px;
  }

  .tf-button--small,
  .wt-button--small {
    font-size: 14px;
    padding: 5px 13px;
  }

  .tf-button--large.has-icon,
  .tf-button--medium.has-icon,
  .wt-button--large.has-icon,
  .wt-button--medium.has-icon {
    svg {
      height: 15px;
    }
  }

  .tf-button--small.has-icon,
  .wt-button--small.has-icon {
    svg {
      height: 13px;
    }
  }

  .tf-button--icon,
  .tf-button--icon-no-fill,
  .wt-button--icon,
  .wt-button--icon-no-fill {
    padding: 5px 4px;

    span {
      display: inline-block;
      width: 0;
      height: 0;
      overflow: hidden;

      + svg {
        margin-left: 0;
      }
    }
  }

  .tf-button--icon.has-icon,
  .tf-button--icon-no-fill.has-icon,
  .wt-button--icon.has-icon,
  .wt-button--icon-no-fill.has-icon {
    svg {
      width: 14px;
      height: 14px;
    }
  }

  .tf-button--primary,
  .wt-button--primary {
    background-color: $tf-blue;
    border-color: $tf-blue;
    color: $tf-white;
  }

  .tf-button--secondary,
  .wt-button--secondary {
    background-color: transparent;
    border-color: $tf-blue;
    color: $tf-blue;
  }

  .tf-button--affirm,
  .wt-button--affirm {
    color: $tf-white;
    background: $tf-green;
    border-color: $tf-green;
  }

  .tf-button--decline,
  .wt-button--decline {
    color: $tf-white;
    background: $tf-red;
    border-color: $tf-red;
  }

  .tf-button.is-disabled,
  .wt-button.is-disabled {
    background: $tf-extra-light-gray-1;
    color: $tf-light-gray;

    &:not(.tf-button--icon-no-fill),
    &:not(.wt-button--icon-no-fill) {
      border-color: $tf-extra-light-gray-1;
    }
  }

  .tf-button--no-fill,
  .wt-button--no-fill {
    background-color: transparent;
    border-color: transparent;
    color: $tf-blue;
  }

  .tf-button--text,
  .tf-button--text-small,
  .tf-button--text-icon.has-icon,
  .tf-button--text-icon-small.has-icon,
  .tf-button--icon-no-fill.has-icon,
  .wt-button--text,
  .wt-button--text-small,
  .wt-button--text-icon.has-icon,
  .wt-button--text-icon-small.has-icon,
  .wt-button--icon-no-fill.has-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    text-transform: none;
    font-size: 14px;

    svg {
      flex-grow: 0;
      position: static;
    }
  }

  .tf-button--text,
  .tf-button--text-small,
  .tf-button--text-icon.has-icon,
  .tf-button--text-icon-small.has-icon,
  .wt-button--text,
  .wt-button--text-small,
  .wt-button--text-icon.has-icon,
  .wt-button--text-icon-small.has-icon {
    border: 0;
    padding: 0;
  }

  .tf-button--icon-no-fill,
  .wt-button--icon-no-fill {
    padding: 6px;
    border: 2px transparent solid;
    border-radius: 3px;

    &.no-padding {
      padding: 0;
    }

    span {
      position: absolute;
    }

    &:hover:not(.is-disabled) {
      &.tf-button--primary,
      &.wt-button--primary {
        border: 2px $tf-blue solid;
      }

      &.tf-button--affirm,
      &.wt-button--affirm {
        border: 2px $tf-green solid;
      }

      &.tf-button--decline,
      &.wt-button--decline {
        border: 2px $tf-red solid;
      }

      &.no-border, &.no-padding {
        border: 2px transparent solid;
      }
    }
  }

  .tf-button--text-icon-small.has-icon,
  .tf-button--text-small,
  .wt-button--text-icon-small.has-icon,
  .wt-button--text-small {
    font: {
      size: 12px;
      weight: 400;
    }

    .button-text {
      line-height: 21px;
    }
  }

  .tf-button--text-icon.has-icon,
  .tf-button--icon-no-fill.has-icon,
  .wt-button--text-icon.has-icon,
  .wt-button--icon-no-fill.has-icon {
    svg {
      width: 15px;
      height: 15px;
    }
  }

  .tf-button--text-icon-small.has-icon svg,
  .wt-button--text-icon-small.has-icon svg {
    width: 11px;
    height: 11px;
  }

  .tf-button--text.tf-button--primary,
  .tf-button--text-small.tf-button--primary,
  .tf-button--text-icon.tf-button--primary,
  .tf-button--text-icon-small.tf-button--primary,
  .tf-button--icon-no-fill.tf-button--primary,
  .wt-button--text.wt-button--primary,
  .wt-button--text-small.wt-button--primary,
  .wt-button--text-icon.wt-button--primary,
  .wt-button--text-icon-small.wt-button--primary,
  .wt-button--icon-no-fill.wt-button--primary {
    color: $tf-blue;
  }

  .tf-button--text.tf-button--affirm,
  .tf-button--text-small.tf-button--affirm,
  .tf-button--text-icon.tf-button--affirm,
  .tf-button--text-icon-small.tf-button--affirm,
  .tf-button--icon-no-fill.tf-button--affirm,
  .wt-button--text.wt-button--affirm,
  .wt-button--text-small.wt-button--affirm,
  .wt-button--text-icon.wt-button--affirm,
  .wt-button--text-icon-small.wt-button--affirm,
  .wt-button--icon-no-fill.wt-button--affirm {
    color: $tf-green;
  }

  .tf-button--text.tf-button--decline,
  .tf-button--text-small.tf-button--decline,
  .tf-button--text-icon.tf-button--decline,
  .tf-button--text-icon-small.tf-button--decline,
  .tf-button--icon-no-fill.tf-button--decline,
  .wt-button--text.wt-button--decline,
  .wt-button--text-small.wt-button--decline,
  .wt-button--text-icon.wt-button--decline,
  .wt-button--text-icon-small.wt-button--decline,
  .wt-button--icon-no-fill.wt-button--decline {
    color: $tf-red;
  }

  .tf-button--text[disabled],
  .tf-button--text-small[disabled],
  .tf-button--text-icon[disabled],
  .tf-button--text-icon-small[disabled],
  .tf-button--icon-no-fill[disabled],
  .wt-button--text[disabled],
  .wt-button--text-small[disabled],
  .wt-button--text-icon[disabled],
  .wt-button--text-icon-small[disabled],
  .wt-button--icon-no-fill[disabled] {
    background: transparent;
    color: $tf-light-gray;
  }

  /* table buttons */
  .tf-button--table-sort,
  .wt-button--table-sort {
    position: relative;
    background: transparent;
    border: 0;
    text-transform: none;
    padding: 0;
    color: $tf-dark-gray;
    padding-right: 16px;
    top: -2px;
  }

  .table-sort {
    position: absolute;
    right: 0;
    top: -4px;
    width: 8px;

    svg {
      position: absolute;
      right: 0;
      top: 0;
      width: 8px;
      fill: $tf-dark-gray;
    }

    svg + svg {
      top: 9px;
      transform: rotateZ(180deg);
    }

    &.table-sort-selected.table-sort-asc {
      svg:first-of-type {
        fill: $tf-green;
      }
    }

    &.table-sort-selected.table-sort-desc {
      svg + svg {
        fill: $tf-green;
      }
    }
  }

  // Add margin to span for appended icons
  svg + .button-text,
  .button-text + svg {
    margin-left: 6px;
  }
</style>
