<template>
  <div
    class="l-tooltip-container"
    :class="containerClasses"
    @click="toggleTooltip"
    @mouseleave="trigger === 'click-permanent' ? null : hideTooltip()"
  >
    <slot />
    <div
      v-if="(show || trigger === 'hover') && visible"
      class="l-tooltip"
      :class="classes"
      :style="{
        '--tooltip-bg': tooltipBG,
        '--tooltip-border': tooltipBorder,
        '--tooltip-text': tooltipText,
        '--tooltip-radius': tooltipRadius,
      }"
    >
      <span
        v-if="label"
        class="l-tooltip-label"
      >{{ label }}</span>
      <span
        v-if="description"
        class="l-tooltip-description"
      >
        {{ description }}
      </span>
      <slot
        v-if="hasBodySlot"
        name="tooltipBody"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: "LTooltip",
  props: {
    /**
     * The label of the tooltip.
     */
    label: {
      type: String,
    },
    /**
     * The description of the tooltip.
     */
    description: {
      type: String,
    },
    /**
     * The type of the tooltip.
     */
    type: {
      type: String,
      default: "black",
      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,
      default: "50",
      validator: function (value) {
        return (
          [
            "50",
            "100",
            "200",
            "300",
            "400",
            "500",
            "600",
            "700",
            "800",
            "900",
          ].indexOf(value) !== -1
        );
      },
    },
    /**
     * The radius of the tooltip.
     */
    radius: {
      type: String,
      default: "lg",
      validator: function (value) {
        return (
          ["sm", "base", "md", "lg", "xl", "2xl", "3xl", "full"].indexOf(
            value
          ) !== -1
        );
      },
    },
    /**
     * The trigger of the tooltip.
     */
    trigger: {
      type: String,
      default: "hover",
      validator: function (value) {
        return (
          ["hover", "click", "click-autohide", "click-permanent"].indexOf(
            value
          ) !== -1
        );
      },
    },
    /**
     * The position of the tooltip.
     */
    position: {
      type: String,
      default: "top",
      validator: function (value) {
        return ["top", "right", "bottom", "left"].indexOf(value) !== -1;
      },
    },
    /**
     * Whether to show the tooltip
     */
    visible: {
      type: Boolean,
      required: false,
      default: () => true
    }
  },
  data() {
    return {
      show: false,
    };
  },
  computed: {
    classes() {
      return ["l-tooltip--" + this.type, "l-tooltip--" + this.position];
    },
    containerClasses() {
      return ["l-tooltip-container--" + this.trigger];
    },
    tooltipRadius() {
      return `var(--radius-${this.radius})`;
    },
    tooltipBG() {
      if (this.type === "white" || this.type === "black") {
        return `var(--${this.type})`;
      }
      return `var(--${this.type}-${this.shade})`;
    },
    tooltipBorder() {
      if (this.type === "white") {
        return `var(--neutral-100)`;
      }
      if (this.type === "black") {
        return `var(--${this.type})`;
      }
      return `var(--${this.type}-${Number(this.shade) - 100})`;
    },
    tooltipText() {
      if (this.type === "white") {
        return `var(--black)`;
      }
      if (this.type === "black") {
        return `var(--white)`;
      }
      if (Number(this.shade) > 300) {
        return `var(--${this.type}-50)`;
      }
      return `var(--${this.type}-900)`;
    },
    hasBodySlot() {
      return !!this.$slots.default;
    },
  },
  methods: {
    toggleTooltip() {
      if (
        this.trigger === "click" ||
        this.trigger === "click-autohide" ||
        this.trigger === "click-permanent"
      ) {
        this.show = !this.show;
        this.$emit("tooltipOpen", this.show);
      }
    },
    hideTooltip() {
      if (
        this.trigger === "click" ||
        this.trigger === "click-autohide" ||
        this.trigger === "hover"
      ) {
        this.show = false;
        this.$emit("tooltipOpen", this.show);
      }
    },
  },
};
</script>

<style>
.l-tooltip-container {
  position: relative;
  display: inline-flex;
}
.l-tooltip {
  position: absolute;
  top: calc(100% + var(--spacing-1-5) - var(--spacing-4));
  left: 50%;
  transform: translate(-50%, 0);
  display: none;
  flex-direction: column;
  gap: var(--spacing-0-5);
  padding: var(--spacing-1) var(--spacing-2-5);
  background-color: var(--tooltip-bg);
  color: var(--tooltip-text);
  font-size: var(--sizing-xs);
  border-radius: var(--tooltip-radius);
  text-decoration: none;
  user-select: none;
  box-shadow: var(--shadow-lg);
  border: var(--tooltip-border) 0.5px solid;
  animation: var(--animation-fade);
  animation-duration: var(--duration-500);
  animation-delay: var(--duration-150);
  animation-timing-function: var(--ease-1);
  animation-fill-mode: both;
  z-index: var(--layer-top);
}
/* .l-tooltip::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: auto;
  width: var(--spacing-2-5);
  height: var(--spacing-2-5);
  transform: rotate(45deg) translate(-30%, -30%);
  background-color: var(--tooltip-bg);
  border-radius: var(--radius-sm);
} */
/* Tooltip positions */
.l-tooltip--top {
  top: auto;
  bottom: 100%;
  bottom: calc(100% + var(--spacing-0-5));
}
.l-tooltip--top::after {
  top: auto;
  bottom: 0;
  transform: rotate(45deg) translate(30%, 30%);
}
.l-tooltip--bottom {
  top: 100%;
  top: calc(100% + var(--spacing-1-5) - var(--spacing-4));
  bottom: auto;
}
.l-tooltip--bottom::after {
  top: 0;
  bottom: auto;
  transform: rotate(45deg) translate(-30%, -30%);
}

.l-tooltip--right {
  top: calc(50% + var(--spacing-4));
  left: calc(100% - var(--spacing-4));
  transform: translate(var(--spacing-3), -50%);
}
.l-tooltip--right::after {
  left: 0;
  margin: 0;
  transform: rotate(45deg) translate(50%, 100%);
}

.l-tooltip--left {
  top: calc(50% + var(--spacing-4));
  right: auto;
  left: var(--spacing-4);
  transform: translate(calc(-100% - var(--spacing-3)), -50%);
}
.l-tooltip--left::after {
  left: auto;
  right: 0;
  margin: 0;
  transform: rotate(45deg) translate(100%, 40%);
}

.l-tooltip-label {
  white-space: nowrap;
  font-weight: bold;
}
.l-tooltip-description {
  min-width: var(--spacing-80);
}
/* Types */
.l-tooltip--white {
  background-color: var(--white);
  color: inherit;
}
.l-tooltip--black {
  background-color: var(--black);
  border-color: var(--black);
  color: var(--tooltip-text);
}

/* Interactivity */
.l-tooltip-container:hover .l-tooltip {
  display: inline-flex;
}
.l-tooltip-container--click-permanent .l-tooltip {
  display: inline-flex;
}
</style>
