<script setup lang="ts">
import { computed } from "vue";
import { IProps } from "./props";

const emit = defineEmits(["click"]);

const props = withDefaults(defineProps<IProps>(), {
  disabled: false,
  outline: false,
  variant: "primary",
  loading: false,
  fullSize: false,
});

const cssClasses = computed<string[]>(() => {
  let classes: string[] = [];

  props.outline ? classes.push(`button-outline-${props.variant}`) : classes.push(`button-${props.variant}`);
  props.fullSize ? classes.push("button-full") : null;
  return classes;
});

const opacityIsLoading = computed<string>(() => {
  if (props.loading) {
    return "opacity: 0.5;";
  }
  return "";
});

const colorSpinner = computed<string>(() => {
  if (props.outline) {
    const colors = {
      primary: "var(--primary-500)",
      secondary: "var(--secondary-500)",
      orange: "var(--orange-500)",
      red: "var(--red-500)",
      "green-dark": "var(--green-dark-500)",
      "gray-dark": "var(--gray-500)",
      alternative: "var(--secondary-500)",
    };
    return colors[props.variant];
  }

  if (props.variant === "alternative") {
    return "var(--primary-500)";
  }

  return "var(--gray-white)";
});

function click(event: MouseEvent) {
  if (event.type === "click") {
    emit("click");
  }
}
</script>

<template>
  <button :class="['button', ...cssClasses]" :disabled="disabled" @click.prevent="click">
    <div v-show="loading" class="container-spinner">
      <div class="spinner" />
    </div>

    <div class="content" :style="opacityIsLoading">
      <slot />
    </div>
  </button>
</template>

<style lang="scss" scoped>
.button {
  position: relative;
  border: none;
  outline: none;
  font-weight: var(--weight-semibold);
  height: var(--h-11);
  padding: var(--spacing-0) var(--spacing-8);
  border-radius: var(--radius-lg);
  font-size: var(--font-sm);
  border: none;
  outline: none;
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2);
  border: 1px solid transparent;
  user-select: none;

  .content {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-3);
    text-wrap: nowrap;
    overflow: hidden;
  }

  &:disabled {
    opacity: 0.3;
    cursor: not-allowed;
    .spinner {
      background:
        radial-gradient(farthest-side, #ffffff 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, #ffffff);
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), #ffffff 0);
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), #ffffff 0);
    }
  }
  &:hover {
    .spinner {
      background:
        radial-gradient(farthest-side, #ffffff 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, #ffffff);
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), #ffffff 0);
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), #ffffff 0);
    }
  }

  @include size(lg) {
    font-size: var(--font-xs);
  }
  @include size(sm) {
    height: var(--h-11);
    font-size: var(--font-xs);
  }
}

.button-full {
  width: 100%;
}

.button-primary {
  color: var(--gray-white);
  background: var(--primary-500);
  &:hover {
    color: var(--gray-white);
    background: var(--primary-400);
  }
  &:focus {
    background: var(--primary-600);
  }
  &:disabled {
    background: var(--primary-500);
  }
}

.button-outline-primary {
  color: var(--primary-500);
  background: var(--gray-white);
  border: 1.5px solid var(--primary-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--primary-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--primary-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--primary-500);
  }
}

.button-secondary {
  color: var(--gray-white);
  background: var(--secondary-500);
  &:hover {
    color: var(--gray-white);
    background: var(--secondary-400);
  }
  &:focus {
    background: var(--secondary-600);
  }
  &:disabled {
    background: var(--secondary-500);
  }
}

.button-outline-secondary {
  color: var(--secondary-500);
  background: var(--gray-white);
  border: 1.5px solid var(--secondary-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--secondary-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--secondary-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--secondary-500);
  }
}

.button-alternative {
  color: var(--primary-500);
  background: var(--primary-50);
  &:hover {
    color: var(--primary-500);
    background: var(--primary-100);
    .spinner {
      background:
        radial-gradient(farthest-side, var(--primary-500) 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, var(--primary-500)) !important;
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0) !important;
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0) !important;
    }
  }
  &:focus {
    background: var(--primary-100);
  }
  &:disabled {
    background: var(--primary-100);
    .spinner {
      background:
        radial-gradient(farthest-side, var(--primary-500) 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, var(--primary-500));
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0);
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0);
    }
  }
}

.button-outline-alternative {
  color: var(--primary-500);
  background: var(--gray-white);
  border: 1.5px solid var(--primary-500) !important;
  &:hover {
    color: var(--primary-500);
    background: var(--primary-50);

    .spinner {
      background:
        radial-gradient(farthest-side, var(--primary-500) 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, var(--primary-500)) !important;
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0) !important;
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0) !important;
    }
  }
  &:focus {
    color: var(--primary-500);
    background: var(--primary-100);
  }
  &:disabled {
    color: var(--primary-500);
    background: var(--primary-100);

    .spinner {
      background:
        radial-gradient(farthest-side, var(--primary-500) 94%, #0000) top/3.8px 3.8px no-repeat,
        conic-gradient(#0000 30%, var(--primary-500));
      -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0);
      mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), var(--primary-500) 0);
    }
  }
}

.button-orange {
  color: var(--gray-white);
  background: var(--orange-500);
  &:hover {
    color: var(--gray-white);
    background: var(--orange-400);
  }
  &:focus {
    background: var(--orange-600);
  }
  &:disabled {
    background: var(--orange-500);
  }
}

.button-outline-orange {
  color: var(--orange-500);
  background: var(--gray-white);
  border: 1.5px solid var(--orange-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--orange-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--orange-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--orange-500);
  }
}

.button-red {
  color: var(--gray-white);
  background: var(--red-500);
  &:hover {
    color: var(--gray-white);
    background: var(--red-400);
  }
  &:focus {
    background: var(--red-600);
  }
  &:disabled {
    background: var(--red-500);
  }
}

.button-outline-red {
  color: var(--red-500);
  background: var(--gray-white);
  border: 1.5px solid var(--red-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--red-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--red-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--red-500);
  }
}

.button-green-dark {
  color: var(--gray-white);
  background: var(--green-dark-500);
  &:hover {
    color: var(--gray-white);
    background: var(--green-dark-400);
  }
  &:focus {
    background: var(--green-dark-600);
  }
  &:disabled {
    background: var(--green-dark-500);
  }
}

.button-outline-green-dark {
  color: var(--green-dark-500);
  background: var(--gray-white);
  border: 1.5px solid var(--green-dark-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--green-dark-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--green-dark-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--green-dark-500);
  }
}

.button-gray-dark {
  color: var(--gray-50);
  background: var(--gray-500);
  &:hover {
    color: var(--gray-white);
    background: var(--gray-400);
  }
  &:focus {
    background: var(--gray-400);
  }
  &:disabled {
    background: var(--gray-500);
  }
}

.button-outline-gray-dark {
  color: var(--gray-500);
  background: var(--gray-white);
  border: 1.5px solid var(--gray-500) !important;
  &:hover {
    color: var(--gray-white);
    background: var(--gray-400);
  }
  &:focus {
    color: var(--gray-white);
    background: var(--gray-500);
  }
  &:disabled {
    color: var(--gray-white);
    background: var(--gray-500);
  }
}

.container-spinner {
  position: absolute;
  width: 90%;
  height: 98%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background-color: transparent !important;
  backdrop-filter: blur(0.3px) !important;
  transition: var(--transition);

  .spinner {
    width: var(--w-6);
    height: var(--h-6);
    border-radius: var(--radius-full);
    transition: var(--transition);
    background:
      radial-gradient(farthest-side, v-bind(colorSpinner) 94%, #0000) top/3.8px 3.8px no-repeat,
      conic-gradient(#0000 30%, v-bind(colorSpinner));
    -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), v-bind(colorSpinner) 0);
    mask: radial-gradient(farthest-side, #0000 calc(100% - 3.8px), v-bind(colorSpinner) 0);
    animation: spinner 0.6s infinite linear;
  }

  @keyframes spinner {
    to {
      transform: rotate(360deg);
    }
  }
}

@keyframes spinner {
  100% {
    transform: rotate(1turn);
  }
}

@keyframes opacity {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
</style>
