<script setup lang="ts">
import {motion, frame} from "motion-v";
const {
    name,
    img = undefined,
    color = 'bg-white',
    textTop = false,
    moveFactor = undefined,
    scaleFactor = 2,
    initialWidth = undefined,
    initialHeight = undefined,
} = defineProps<{
    name: string,
    img?: string,
    color?: string,
    textTop?: boolean,
    moveFactor?: number,
    scaleFactor?: number,
    initialWidth?: string,
    initialHeight?: string,
}>()

const emit = defineEmits(['positionChanged'])

const isHoveringParent = ref(false)
const roundedDivClass = `rounded-full w-full h-full absolute ${color}`

function getRandomArbitrary(min: number, max: number): number {
    return Math.random() * (max - min) + min;
}

const moveFactorValue = moveFactor ? moveFactor : getRandomArbitrary(8.0, 30.0)

const spring = {damping: 5, stiffness: 50, restDelta: 0.001}

const elementRef = useTemplateRef('elementRef')
const xPoint = useMotionValue(0)
const yPoint = useMotionValue(0)
const x = useSpring(xPoint, spring)
const y = useSpring(yPoint, spring)
const handlePointerMove = ({clientX, clientY}: { clientX: number; clientY: number }) => {
    const element = elementRef.value?.$el
    if (!element) return
    frame.read(() => {
        xPoint.set((clientX - element.offsetLeft - element.offsetWidth / 2)/moveFactorValue)
        yPoint.set((clientY - element.offsetTop - element.offsetHeight / 2)/moveFactorValue)
    })
}

useRafFn(() => {
    const element = elementRef.value?.$el
    if (!element)
        return
    emit(
        'positionChanged',
        x.get() + element.offsetLeft + element.offsetWidth/2,
        y.get() + element.offsetTop + element.offsetHeight/2,)
})

onMounted(() => {
    window.addEventListener("pointermove", handlePointerMove)
})

onUnmounted(() => {
    window.removeEventListener("pointermove", handlePointerMove)
})

const baseElementClass = ref(`${initialWidth ? initialWidth : 'w-30'} ${initialHeight ? initialHeight : 'h-30'} avatar absolute`)

</script>

<template>
    <motion.div
        ref="elementRef"
        :class="baseElementClass"
        :style="{ x, y }"
        :while-hover="{ scale: scaleFactor }"
        @hover-start="event => {isHoveringParent=true}"
        @hover-end="event => {isHoveringParent=false}">

        <div v-if="img !== undefined" class="mask mask-squircle w-full">
            <NuxtImg :src="img"/>
        </div>
        <div v-else :class="roundedDivClass"/>

        <motion.p
            v-if="textTop"
            v-show="isHoveringParent"
            class="-top-8 absolute text-xs"
            :initial="{ opacity: 0 }"
            :animate="{ opacity: 1 }"
            :exit="{ opacity: 0 }">
            {{ name }}
        </motion.p>

        <motion.p
            v-else
            v-show="isHoveringParent"
            class="-bottom-8 absolute text-xs"
            :initial="{ opacity: 0 }"
            :animate="{ opacity: 1 }"
            :exit="{ opacity: 0 }">
            {{ name }}
        </motion.p>
    </motion.div>
</template>

<style scoped>
* {
    overflow: visible;
}
</style>