<template>
  <button
    :disabled="disabled"
    :class="[buttonClasses, wrapperClass]"
    v-bind="$attrs"
    v-on="updatedListeners"
  >
    <slot name="loader">
      <div v-if="loading" class="n-btn-loader-wrapper">
        <svg
          class="loading-icon"
          width="20"
          height="20"
          viewBox="0 0 20 20"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <g id="vuesax/linear/refresh">
            <g id="refresh">
              <path
                id="Vector"
                d="M12.1263 18.0582C15.7013 17.1165 18.3346 13.8665 18.3346 9.99984C18.3346 5.39984 14.6346 1.6665 10.0013 1.6665C4.44297 1.6665 1.66797 6.29984 1.66797 6.29984M1.66797 6.29984V2.49984M1.66797 6.29984H3.34297H5.36797"
                stroke="white"
                stroke-width="1.5"
                stroke-linecap="round"
                stroke-linejoin="round"
              />
              <path
                id="Vector_2"
                d="M1.66797 10C1.66797 14.6 5.4013 18.3333 10.0013 18.3333"
                stroke="white"
                stroke-width="1.5"
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-dasharray="3 3"
              />
            </g>
          </g>
        </svg>
      </div>
    </slot>
    <slot name="prepend-icon">
      <div
        v-if="prependIcon"
        :class="[prependIcon, 'n-icon n-icon-placeholder n-icon-size-20']"
      />
    </slot>

    <slot />

    <slot name="append-icon">
      <div
        v-if="appendIcon"
        :class="[appendIcon, 'n-icon n-icon-placeholder n-icon-size-20']"
      />
    </slot>
  </button>
</template>

<script>
export default {
  name: "NButton",
  props: {
    wrapperClass: {
      type: String,
      default: "",
    },
    prependIcon: {
      type: String,
      default: "",
    },
    appendIcon: {
      type: String,
      default: "",
    },
    size: {
      type: String,
      default: "normal",
      validator(value) {
        return ["normal", "lg", "sm"].includes(value);
      },
    },
    variant: {
      type: String,
      default: "contained",
      validator(value) {
        return ["contained", "outlined", "text"].includes(value);
      },
    },
    color: {
      type: String,
      default: "primary",
      validator(value) {
        return [
          "primary",
          "white",
          "success",
          "info",
          "danger",
          "warning",
        ].includes(value);
      },
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    block: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    updatedListeners() {
      const { $listeners, onClick } = this;
      const enhancedListeners = JSON.parse(JSON.stringify($listeners));

      enhancedListeners.click = onClick;

      return enhancedListeners;
    },
    buttonClasses() {
      const { block, disabled, variantClass, colorClass, sizeClass } = this;
      let classes = "n-btn n-pkg-base-btn";

      if (variantClass) {
        classes += variantClass;
      }

      if (sizeClass) {
        classes += sizeClass;
      }

      if (colorClass) {
        classes += colorClass;
      }

      if (block) {
        classes += " n-btn--block";
      }

      if (disabled) {
        classes += " n-btn--disabled";
      }

      return classes;
    },
    variantClass() {
      const { variant } = this;
      const isValidVariant = ["contained", "outlined", "text"].includes(
        variant
      );

      if (!isValidVariant) {
        return "";
      }

      return ` n-btn--${variant}`;
    },
    colorClass() {
      const { variant, color } = this;
      const isValidColor = [
        "primary",
        "white",
        "success",
        "info",
        "danger",
        "warning",
      ].includes(color);

      if (!isValidColor) {
        return "";
      }

      return ` n-btn-${variant}--${color}`;
    },
    sizeClass() {
      const { size } = this;
      const isValidSize = ["lg", "sm"].includes(size);

      if (!isValidSize) {
        return "";
      }

      return ` n-btn--${size}`;
    },
  },
  methods: {
    onClick(e) {
      const { loading, disabled, $listeners } = this;

      if (!loading && !disabled) {
        $listeners.click(e);
      }
    },
  },
};
</script>

<style scoped>
@import url("./n-button.css");
</style>
