<template>
  <div
    class="loyalty-suite-tooltip__wrapper"
    ref="wrapper"
    @click="toggle"
    @mouseenter="show"
    @mouseleave="hide"
  >
    <slot />
    <teleport to="body">
      <div
        v-if="visible"
        class="loyalty-suite-tooltip"
        :class="`loyalty-suite-tooltip--${position}`"
        :style="tooltipStyle"
        ref="tooltip"
      >
        {{ text }}
      </div>
    </teleport>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  onMounted,
  onBeforeUnmount,
  nextTick,
  computed,
} from 'vue';

export default defineComponent({
  name: 'Tooltip',
  props: {
    text: {
      type: String,
      required: true,
    },
    position: {
      type: String as () => 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right',
      default: 'top-left',
    },
  },
  setup(props) {
    const visible = ref(false);
    const isMobile = ref(false);
    const wrapper = ref<HTMLElement | null>(null);
    const tooltip = ref<HTMLElement | null>(null);

    const tooltipStyle = ref({ top: '0px', left: '0px' });

    const updatePosition = () => {
      if (!wrapper.value || !tooltip.value) return;

      const trigger = wrapper.value.getBoundingClientRect();
      const tip = tooltip.value.getBoundingClientRect();

      const margin = 8;

      const coords = {
        top: 0,
        left: 0,
      };

      switch (props.position) {
        case 'top-left':
          coords.top = trigger.top - tip.height - margin + window.scrollY;
          coords.left = trigger.left + window.scrollX;
          break;
        case 'top-right':
          coords.top = trigger.top - tip.height - margin + window.scrollY;
          coords.left = trigger.right - tip.width + window.scrollX;
          break;
        case 'bottom-left':
          coords.top = trigger.bottom + margin + window.scrollY;
          coords.left = trigger.left + window.scrollX;
          break;
        case 'bottom-right':
          coords.top = trigger.bottom + margin + window.scrollY;
          coords.left = trigger.right - tip.width + window.scrollX;
          break;
      }

      tooltipStyle.value = {
        position: 'absolute',
        top: `${coords.top}px`,
        left: `${coords.left}px`,
      };
    };

    const show = () => {
      if (!isMobile.value) {
        visible.value = true;
        nextTick(updatePosition);
      }
    };

    const hide = () => {
      if (!isMobile.value) visible.value = false;
    };

    const toggle = () => {
      if (isMobile.value) {
        visible.value = !visible.value;
        nextTick(updatePosition);
      }
    };

    const handleClickOutside = (event: MouseEvent) => {
      if (
        isMobile.value &&
        visible.value &&
        wrapper.value &&
        !wrapper.value.contains(event.target as Node)
      ) {
        visible.value = false;
      }
    };

    const detectDevice = () => {
      isMobile.value = window.innerWidth <= 1024;
    };

    onMounted(() => {
      detectDevice();
      window.addEventListener('resize', detectDevice);
      window.addEventListener('scroll', updatePosition, true);
      document.addEventListener('click', handleClickOutside);
    });

    onBeforeUnmount(() => {
      window.removeEventListener('resize', detectDevice);
      window.removeEventListener('scroll', updatePosition, true);
      document.removeEventListener('click', handleClickOutside);
    });

    return {
      visible,
      show,
      hide,
      toggle,
      tooltipStyle,
      wrapper,
      tooltip,
      position: props.position,
    };
  },
});
</script>

<style scoped>
.loyalty-suite-tooltip__wrapper {
  position: relative;
  display: inline-flex;
  cursor: help;
}

.loyalty-suite-tooltip {
  display: flex;
  z-index: 999999;
  background: var(--loyalty-suite-dark);
  color: var(--loyalty-suite-light);
  font-size: 13px;
  font-weight: 400;
  padding: 6px 10px;
  border-radius: 4px;
  pointer-events: none;
  max-width: 280px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
</style>
