<script setup lang="ts">
import type { CalendarEvent } from './CalendarTypes'
import { Card, useDevice } from '@bagelink/vue'
import { ref, computed } from 'vue'

const props = defineProps<{
	event?: CalendarEvent
	targetElement?: HTMLElement
	position?: { top: number, left: number }
	show: boolean
	hasEventContentSlot: boolean
}>()
const emit = defineEmits<{
	(e: 'close'): void
	(e: 'eventClick', event: CalendarEvent): void
}>()
const { scrollY, scrollX, innerHeight, innerWidth } = useDevice()
const popoverRef = ref<HTMLElement>()

const popoverPosition = computed(() => {
	const popoverWidth = 400
	const margin = 10

	if (props.position) {
		// If position is directly provided, use it
		let { top, left } = props.position
		top -= 80

		// Keep popover within viewport bounds
		top = Math.max(scrollY.value + margin, Math.min(top, innerHeight.value + scrollY.value - 150 - 10))
		left = Math.max(scrollX.value + margin, Math.min(left, innerWidth.value + scrollX.value - popoverWidth - margin))

		return { top, left, width: popoverWidth, height: 150 }
	} if (props.targetElement && props.show) {
		// Position relative to target element
		const target = props.targetElement
		const rect = target.getBoundingClientRect()

		let top = rect.top + scrollY.value + (rect.height / 2) - (150 / 2)
		let left = rect.left + scrollX.value + rect.width + margin

		// Keep popover within viewport bounds
		top = Math.max(scrollY.value + margin, Math.min(top, innerHeight.value + scrollY.value - 150 - 10))

		// If it would go off right side, position to the left instead
		if (left + popoverWidth > innerWidth.value + scrollX.value) {
			left = rect.left + scrollX.value - popoverWidth + rect.width - margin
		}

		if (left < scrollX.value) left = rect.right + scrollX.value + margin

		return { top, left, width: popoverWidth, height: 150 }
	}
	return { top: 0, left: 0, width: popoverWidth, height: 150 }
})

function closePopover() {
	emit('close')
}
</script>

<template>
	<Card
		v-if="show && event" ref="popoverRef" v-click-outside="closePopover" thin class="custom-popover" :style="{
			top: `${popoverPosition.top}px`,
			left: `${popoverPosition.left}px`,
			maxWidth: `${popoverPosition.width}px`,
		}"
	>
		<slot name="eventContent" :event="event" :close="closePopover" />
	</Card>
</template>

<style scoped>
.custom-popover {
	position: fixed;
	z-index: 1000;
	min-width: 250px;
	max-width: 350px;
	background-color: white;
	border-radius: var(--btn-border-radius);
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
	animation: fadeIn 0.2s ease;
	transform-origin: center left;
}

@keyframes fadeIn {
	from {
		opacity: 0;
		transform: scale(0.95);
	}

	to {
		opacity: 1;
		transform: scale(1);
	}
}
</style>
