<script lang="tsx">
import {
  ref, type Ref, onMounted, onUpdated, Teleport, defineComponent, type PropType,
} from 'vue'
import type { TooltipActionInterface } from './types'

/**
 * Компонент-обертка для отображения тултипа при наведении курсора.
 * <p>
 *   <a href="https://www.figma.com/file/Q4Z4CnFx4i0qhD5fbgnPpf/%F0%9F%92%BB-%D0%94%D0%B8%D0%B7%D0%B0%D0%B9%D0%BD-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-ARK-SPACE?type=design&node-id=6204%3A150539&mode=dev" target="_blank">Дизайн</a>
 * </p>
 */

export default defineComponent({
  props: {
    /**
     * Объект, представляющий дополнительное действие, связанное с тултипом.
     * Содержит свойства callback и icon для обработки события и отображения иконки соответственно.
     */
    action: {
      type: [Object, null] as PropType<TooltipActionInterface | null>,
      default: null,
    },
    /**
     * При значении props.bottom=true тултип будет отображаться ПОД элементом.
     * По умолчанию НАД.
     */
    bottom: {
      type: Boolean,
      default: false,
    },
    /**
     * При значении props.center=true тултип будет отображаться ПО ЦЕНТРУ элемента.
     */
    center: {
      type: Boolean,
      default: false,
    },
    /**
     * Флаг, позволяющий отображать тултип в зависимости от последнего положения курсора при наведении.
     */
    isCursorTracked: {
      type: Boolean,
      default: false,
    },
    /**
     * Флаг, для прилипания тултипа к левому-правому краю. По умолчанию тултип у левого края.
     * Для прилипания к правому краю - установить true.
     */
    left: {
      type: Boolean,
      default: false,
    },
    /**
     * Флаг, для прилипания тултипа к правому краю.
     */
    right: {
      type: Boolean,
      default: false,
    },
    /**
     * Опция установки максимальной ширины тултипа в px.
     */
    maxWidth: {
      type: Number,
      default: 250,
    },
    /**
     * Корректировка позиции тултипа по вертикали.
     */
    positionCorrectingY: {
      type: Number,
      default: 0,
    },
    /**
     * Корректировка позиции тултипа по горизонтали.
     */
    positionCorrectingX: {
      type: Number,
      default: 0,
    },
    /**
     * Текст, отображаемый внутри тултипа.
     */
    text: {
      type: String,
      required: true,
    },

    /**
     * Принудительное отключение отображения тултипа
     */
    forcedDisable: {
      type: Boolean,
      default: false,
    },
  },

  setup(props, ctx) {
    const element = ref(null) as unknown as Ref<HTMLDivElement>
    const parentElement = ref(null) as unknown as Ref<HTMLDivElement>

    const top = ref(0)
    const left = ref(0)
    const opacity = ref<0 | 1>(0)

    function setOpacity(value: typeof opacity['value']) {
      opacity.value = value
    }

    function onShow(e: MouseEvent) {
      if (props.forcedDisable) return

      setOpacity(1)

      if (props.isCursorTracked) {
        const elementRect = element.value.getBoundingClientRect()

        top.value = e.clientY - 10
        left.value = e.clientX - (elementRect.width / 2)
      }
    }

    function calculatePosition() {
      const parentRect = parentElement.value.getBoundingClientRect()

      top.value = parentRect.top
      left.value = props.left ? parentRect.right : props.right
        ? parentRect.left + parentElement.value.clientWidth + 4
        : parentRect.left
    }

    if (!props.isCursorTracked) {
      onMounted(calculatePosition)
      onUpdated(calculatePosition) // Нужен для условных асинхронных отрисовок
    }

    return () => (
      <div
        ref={parentElement}
        class="ark-ui-tooltip"
        onMouseover={onShow}
        onMouseout={() => setOpacity(0)}
      >
        <span>{ctx?.slots?.default && ctx.slots.default()}</span>

        {props.text.length > 0 && (
          <Teleport to="body">
            <span
              v-html={props.text}
              onMouseover={onShow}
              onMouseout={() => setOpacity(0)}
              onClick={props.action?.callback}
              id={props.text}
              ref={element}
              class={`
                ark-ui-tooltip-cloud
                ${props.bottom ? 'bottom' : ''}
                ${props.center ? 'center' : ''}
                ${props.left ? 'right' : ''}
                ${props.action ? props.action.icon : ''}
              `}
              style={`
                left: ${left.value + props.positionCorrectingX}px;
                top: ${top.value + props.positionCorrectingY}px;
                opacity: ${opacity.value};
                max-width: ${props.maxWidth}px;
                pointer-events: ${props.action ? 'auto' : 'none'};
                cursor: ${props.action ? 'pointer' : 'auto'};
              `}
            >
            </span>
          </Teleport>
        )}
      </div>
    )
  },
})
</script>

<style lang="scss" scoped>
@import '../../styles/styles.scss';
</style>
