<template>
  <div
    ref="tooltipRef"
    class="ui-tooltip"
    @mouseenter="onEnter"
    @mouseleave="onLeave"
    @focusin="onEnter"
    @focusout="onLeave"
  >
    <button
      type="button"
      class="ui-tooltip__trigger"
      @click="onClick"
    >
      <slot name="trigger"/>
    </button>
    <transition name="fade">
      <div
        v-if="isOpen"
        :style="contentStyle"
        class="ui-tooltip__content"
      >
        <slot/>
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { checkDeviceWidth } from '../../runtime';
import { onClickOutside } from '@vueuse/core';
import { CSS_BREAKPOINTS } from '../../config/css-breakpoints';

const props = defineProps<{
  right?: boolean
}>();

const OFFSET = 8;

const tooltipRef = ref<HTMLElement>();
const isOpen = ref(false);
const contentStyle = ref<Record<string, string>>({});

const breakpoints = CSS_BREAKPOINTS;
const { isMobile } = checkDeviceWidth(breakpoints);

onClickOutside(tooltipRef, () => {
  if (isMobile.value) {
    isOpen.value = false;
  }
});

/** Контент в position: fixed — иначе его режет overflow скроллящихся родителей (список в попапе). */
function open() {
  const rect = tooltipRef.value?.getBoundingClientRect();
  if (!rect) return;

  // На мобиле привязка к триггеру уводит широкий тултип за правый край — прибиваем к вьюпорту.
  if (isMobile.value) {
    contentStyle.value = { top: `${rect.top - OFFSET}px`, left: `${OFFSET}px` };
  } else {
    contentStyle.value = props.right
      ? { top: `${rect.top - OFFSET}px`, left: `${rect.left}px` }
      : { top: `${rect.top - OFFSET}px`, right: `${window.innerWidth - rect.right}px` };
  }

  isOpen.value = true;
}

function onEnter() {
  if (!isMobile.value) {
    open();
  }
}

function onLeave() {
  if (!isMobile.value) {
    isOpen.value = false;
  }
}

function onClick() {
  if (!isMobile.value) return;

  if (isOpen.value) {
    isOpen.value = false;
  } else {
    open();
  }
}
</script>

<style lang="scss">
/* Держим в паре с OFFSET в скрипте: отступ тултипа от края вьюпорта. */
$tooltip-viewport-gap: 8px;

.ui-tooltip {
  position: relative;
  display: inline-flex;
}

.ui-tooltip__trigger {
  display: inline-flex;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.ui-tooltip__content {
  position: fixed;
  transform: translateY(-100%);
  z-index: $z-index-tooltip;
  display: grid;
  padding: 12px;
  background-color: $tooltip-bg;
  border-radius: $radius-lg;
  color: $tooltip-text;
  width: max-content;
  max-width: calc(100vw - #{$tooltip-viewport-gap * 2});
  pointer-events: none;
  box-shadow: $tooltip-shadow;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 100ms ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
