<template>
  <component
    :is="componentType"
    :id="buttonId"
    type="button"
    class="l-button"
    :class="classes"
    :to="to"
    :href="href"
    :style="{
      '--button-bg': buttonBG,
      '--button-hover': buttonHover,
      '--button-hover-text': buttonHoverText,
      '--button-text': buttonText,
      '--button-padding': buttonPadding,
    }"
    :disabled="disabled"
    :value="value"
    @click.stop="onClick"
  >
    <span v-if="label">{{ label }}</span>
    <slot />
  </component>
</template>

<script>
export default {
  name: "LButton",
  props: {
    /**
     * The value of the button.
     */
    value: {
      type: [Boolean, String],
    },
    /**
     * The label of the button.
     */
    label: {
      type: String,
    },
    /**
     * The type of the button.
     */
    type: {
      type: String,
      default: "primary",
      validator: function (value) {
        return (
          [
            "primary",
            "secondary",
            "tertiary",
            "success",
            "warning",
            "danger",
            "neutral",
            "white",
            "black",
            "admin"
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * The shade of the type color.
     */
    shade: {
      type: [String, Number],
      default: "500",
      validator: function (value) {
        return (
          [
            "50",
            "100",
            "200",
            "300",
            "400",
            "500",
            "600",
            "700",
            "800",
            "900",
            50,
            100,
            200,
            300,
            400,
            500,
            600,
            700,
            800,
            900,
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * Outline style of the button.
     */
    outline: {
      type: Boolean,
      default: false,
    },
    /**
     * Icon style of the button.
     */
    icon: {
      type: Boolean,
      default: false,
    },
    /**
     * Pill style button
     */
    pill: {
      type: Boolean,
      default: false,
    },
    /**
     * Text style of the button.
     */
    text: {
      type: Boolean,
      default: false,
    },
    /**
     * The size of the button.
     */
    size: {
      type: String,
      default: "medium",
      validator: function (value) {
        return ["tiny", "small", "medium", "large"].indexOf(value) !== -1;
      },
    },
    /**
     * href - button will act as a native anchor element
     */
    href: {
      type: String,
    },
    /**
     * to - button will act as a nuxt-link
     */
    to: {
      type: [String, Object],
    },
    /**
     * Disable button and click event
     */
    disabled: {
      type: Boolean,
      default: false,
    },
    /**
     * Disable hover styles on button
     */
    disableHover: {
      type: Boolean,
      default: false,
    },
    /**
     * Set button to fill entire container
     */
    block: {
      type: Boolean,
      default: false,
    },
    /**
     * Removes the default padding from the button
     */
    noPadding: {
      type: Boolean,
      default: false,
    },
    /**
     * ID used to identify the button, useful for testing or tracking purposes
     */
    buttonId: {
      type: String,
      default: null,
    }
  },
  computed: {
    classes() {
      return [
        this.disableHover ? "l-button--disable-hover" : null,
        "l-button--" + this.buttonType,
        "l-button-size--" + this.size,
        {
          "l-button--outline": this.outline,
        },
        {
          "l-button--text": this.text,
        },
        {
          "l-button--icon": this.icon,
        },
        {
          "l-button--pill": this.pill,
        },
        {
          "l-button--disabled": this.disabled,
        },
        {
          "l-button--block": this.block,
        },
        {
          "l-button--no-padding": this.noPadding,
        },
      ];
    },
    buttonType() {
      return this.type == "white" || this.type == "black"
        ? this.type
        : this.type + this.shade;
    },
    buttonBG() {
      if (this.type === "white" || this.type === "black") {
        return `var(--${this.type})`;
      }
      return `var(--${this.type}-${this.shade})`;
    },
    buttonText() {
      if (this.type === "white") {
        return `var(--black)`;
      }
      if (this.type === "black") {
        return `var(--white)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--white)`;
      }
      return `var(--${this.type}-900)`;
    },
    buttonHover() {
      if (this.type === "black") {
        return `var(--white)`;
      }
      if (this.type === "white") {
        return `var(--primary-500)`;
      }
      if (Number(this.shade) > 500) {
        return `var(--${this.type}-500)`;
      }
      return `var(--${this.type}-600)`;
    },
    buttonHoverText() {
      if (this.type === "black") {
        return `var(--white)`;
      }
      if (this.type === "white") {
        return `var(--primary-500)`;
      }
      if (this.text === true) {
        if (Number(this.shade) < 400) {
          return `var(--${this.type}-500)`;
        }
      }
      if (this.outline === true && this.type !== "white") {
        if (Number(this.shade) > 300) {
          return `var(--white)`;
        }
      } else if (this.outline === false) {
        return `var(--white)`;
      }
      return `var(--${this.type}-500)`;
    },
    componentType() {
      // if button has to prop, render as nuxt-link, if button has href prop, render as anchor, otherwise render as button
      if (this.to) {
        return "nuxt-link";
      } else if (this.href) {
        return "a";
      } else {
        return "button";
      }
    },
    buttonPadding() {
      if (this.noPadding) {
        return 0;
      } else if (this.size === "tiny") {
        return "var(--spacing-0-5) var(--spacing-3)";
      } else if (this.size === "small") {
        return "var(--spacing-1-5) var(--spacing-4)";
      } else if (this.size === "large") {
        return "var(--spacing-2) var(--spacing-6)";
      } else {
        return "var(--spacing-2) var(--spacing-5)";
      }
    },
  },

  methods: {
    onClick() {
      if (!this.disabled) {
        this.$emit("click");
      }
    },
  },
};
</script>

<style>
.l-button[type="button"],
button.l-button {
  -webkit-appearance: none;
  appearance: none;
}
.l-button {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--spacing-2);
  cursor: pointer;
  padding: var(--button-padding);
  background-color: var(--button-bg);
  border: 1px solid var(--button-bg);
  color: var(--button-text);
  font-size: var(--sizing-base);
  border-radius: var(--radius-lg);
  font-weight: 600;
  transition: all var(--duration-100) ease-in-out;
  text-decoration: none;
  white-space: nowrap;
  position: relative;
  text-transform: capitalize;
}
.l-button:focus {
  outline-color: var(--button-bg);
  outline-width: var(--spacing-0-5);
  outline-offset: var(--spacing-px);
  outline-style: solid;
}
/* Types */
.l-button:hover:not(.l-button--disable-hover) {
  background-color: var(--button-hover);
  border-color: var(--button-hover);
  color: var(--button-hover-text);
}

/* Outline & text style button */
.l-button--outline,
.l-button--text {
  background-color: transparent;
  color: var(--button-bg);
}

.l-button--white {
  color: var(--button-text);
}
.l-button--black {
  color: var(--button-text);
}
.l-button--white:hover:not(.l-button--disable-hover),
.l-button--black:hover:not(.l-button--disable-hover) {
  background-color: var(--button-hover);
  border-color: var(--button-hover);
  color: var(--button-bg);
}

.l-button--text {
  border-color: transparent;
}
.l-button--outline {
  border-color: currentColor;
}

.l-button--outline:hover:not(.l-button--disable-hover) {
  background-color: var(--button-bg);
  color: var(--button-hover-text);
}
.l-button--text:hover:not(.l-button--disable-hover) {
  background-color: var(--button-bg);
  border-color: var(--button-bg);
  color: var(--button-hover-text);
}

.l-button--text.l-button--no-padding:hover {
  background-color: transparent;
  border-color: transparent;
  color: var(--button-hover);
}

.l-button--text.l-button--white,
.l-button--outline.l-button--white {
  color: var(--white);
}
.l-button--outline.l-button--white {
  border-color: var(--white);
}

.l-button--text.l-button--white:hover:not(.l-button--disable-hover),
.l-button--outline.l-button--white:hover:not(.l-button--disable-hover) {
  color: var(--black);
}
.l-button--outline.l-button--white:hover:not(.l-button--disable-hover) {
  border-color: var(--black);
}

/* Sizes */
.l-button-size--tiny {
  font-size: var(--sizing-xs);
  padding: var(--button-padding);
  border-radius: var(--radius-md);
}
.l-button-size--small {
  font-size: var(--sizing-sm);
  padding: var(--button-padding);
  border-radius: var(--radius-md);
}
.l-button-size--large {
  font-size: var(--sizing-lg);
  padding: var(--button-padding);
  border-radius: var(--radius-xl);
}

/* Icon style button */
.l-button--icon {
  padding: var(--spacing-2);
  border-radius: var(--radius-full);
}
.l-button--icon.l-button-size--small {
  padding: var(--spacing-1-5);
  border-radius: var(--radius-full);
}
.l-button--icon.l-button-size--large {
  padding: var(--spacing-2);
  border-radius: var(--radius-full);
}

/* Pill style button */
.l-button--pill {
  border-radius: var(--radius-full) !important;
}

/* Disabled */
.l-button--disabled {
  opacity: 0.45;
}
.l-button--disabled:hover {
  background-color: var(--button-bg);
  border-color: var(--button-bg);
  cursor: not-allowed;
}
.l-button--disabled.l-button--outline {
  background-color: transparent;
  border-color: var(--neutal-500);
  color: var(--neutal-500);
}
.l-button--disabled.l-button--text:hover {
  background-color: transparent;
  border-color: transparent;
  color: var(--button-bg);
}
.l-button--disabled.l-button--outline:hover {
  background-color: var(--neutral-100);
  border-color: var(--neutral-500);
  color: var(--neutral-500);
}

/* Block button */
.l-button--block {
  width: 100%;
  justify-content: center;
}

/* badge inside button */
.l-button .l-badge {
  transform: translate(50%, -50%);
}
</style>
