<!-- prettier-ignore-start -->
<!-- eslint-disable -->
<script setup lang="ts">
import type { DialogWidth, DialogPosition } from './dialogTypes'
import { Btn } from '@bagelink/vue'
import { ref, computed, onMounted, watch } from 'vue'

import { DIALOG_WIDTHS } from './dialogTypes'

const props = withDefaults(defineProps<{
	open: boolean
	title?: string
	width?: DialogWidth
	position?: DialogPosition
	dismissable?: boolean
	flat?: boolean
	thin?: boolean
	centerTitle?: boolean
	closePlacement?: 'header-end' | 'header-start' | 'overlay-start' | 'overlay-end' | 'none'
}>(), {
	width: 'm',
	position: 'center',
	dismissable: true,
	flat: true,
	thin: false,
	centerTitle: false,
	closePlacement: 'header-end'
})

const emit = defineEmits<{
	'update:open': [value: boolean]
	'close': []
}>()

const dialogRef = ref<HTMLDialogElement | null>(null)
const isClosing = ref(false)
const overlayButtonsVisible = ref(true)

const widthStyle = computed(() => DIALOG_WIDTHS[props.width])

const positionClass = computed(() => {
	if (props.position === 'left') return 'dialog-left ms-1 me-auto mt-1 mb-1 height-100-2 m_m-0 m_h-100vh m_max-h-100vh m_radius-0'
	if (props.position === 'right') return 'dialog-right me-1 ms-auto mt-1 mb-1 height-100-2 m_m-0 m_h-100vh m_max-h-100vh m_radius-0'
	if (props.position === 'top') return 'dialog-top mx-auto mt-1 mb-auto'
	if (props.position === 'bottom') return 'dialog-bottom mx-auto mb-1 mt-auto'
	return 'dialog-center mx-auto'
})

// Handle open/close
watch(() => props.open, (isOpen) => {
	if (isOpen) {
		dialogRef.value?.showModal()
		isClosing.value = false
		overlayButtonsVisible.value = false
		// Show overlay buttons after dialog animation completes
		setTimeout(() => {
			overlayButtonsVisible.value = true
		}, 250)
	} else {
		closeWithAnimation()
	}
})

onMounted(() => {
	if (props.open) {
		dialogRef.value?.showModal()
	}
})

function closeWithAnimation() {
	if (isClosing.value) return
	isClosing.value = true
}

function onAnimationEnd() {
	if (isClosing.value) {
		dialogRef.value?.close()
		isClosing.value = false
		emit('close')
	}
}

function onBackdropClick(e: MouseEvent) {
	// Only close if clicking directly on the dialog backdrop (not content)
	if (e.target === dialogRef.value && props.dismissable) {
		emit('update:open', false)
	}
}

function onCancel(e: Event) {
	// Native ESC key triggers cancel event
	if (!props.dismissable) {
		e.preventDefault()
		return
	}
	emit('update:open', false)
}

function close() {
	overlayButtonsVisible.value = false
	emit('update:open', false)
}

defineExpose({ close })
</script>

<template>
	<dialog
		ref="dialogRef" :class="[positionClass, { 'is-closing': isClosing }]"
		:style="{ '--dialog-width': widthStyle }" class="border-none shadow-30 p-0 testMe1" @click="onBackdropClick"
		@cancel="onCancel" @animationend="onAnimationEnd"
	>
		<div class="grid grid-dialog max-height-100-2" @click.stop>
			<!-- Header -->
			<header
				v-if="title || dismissable" class="flex space-between flex-shrink-0 align-items-start gap-05"
				:class="{ 'border-bottom': !flat, 'border-none': !title, 'm_ps-1': title, 'p-05 m_p-05': !title, 'ps-1-5 pe-1 py-1 ': !thin && title, 'ps-1 pe-05 py-05': thin && title }"
			>
				<Btn
					v-if="dismissable && closePlacement === 'header-start'" flat icon="close" aria-label="Close"
					class="dialog-close" thin @click="close"
				/>
				<h3
					v-if="title" class="dialog-title m-0 txt20 semi w-100p word-break-all"
					:class="{ 'txt-center': centerTitle }"
				>
					{{ title }}
				</h3>
				<div v-if="!title" class="flex-grow-1" />
				<Btn
					v-if="dismissable && closePlacement === 'header-end'" flat icon="close" aria-label="Close"
					class="dialog-close" thin @click="close"
				/>
			</header>
			<!-- Body -->
			<div class="overflow-y flex-grow-1 m_p-1" :class="{ 'px-1 py-05': thin, 'px-1-5 py-1': !thin }">
				<slot />
			</div>
			<!-- Footer -->
			<footer
				v-if="$slots.footer" class="flex flex-shrink-0 gap-05 m_px-05 m_py-05 justify-content-end"
				:class="{ 'border-top': !flat, 'px-05 py-05': thin, 'px-1-5 py-1': !thin }"
			>
				<slot name="footer" />
			</footer>
		</div>
		<!-- Overlay close buttons -->
		<Btn
			v-if="dismissable && closePlacement === 'overlay-start' && overlayButtonsVisible" icon="close"
			aria-label="Close" class="fixed top-1 start-1 z-999 overlay-btn" @click="close"
		/>
		<Btn
			v-if="dismissable && closePlacement === 'overlay-end' && overlayButtonsVisible" icon="close"
			aria-label="Close" class="fixed top-1 end-1 z-999 overlay-btn" @click="close"
		/>
	</dialog>
</template>

<style scoped>
/* Base dialog styles */
dialog {
	border-radius: var(--bgl-card-radius, 12px);
	max-width: var(--dialog-width);
	width: calc(100% - 2rem);
	max-height: calc(100vh - 2rem);
	background: var(--bgl-popup-bg, #fff);
	color: var(--bgl-popup-text, black);
}

.grid-dialog {
	grid-template-rows: auto 1fr auto;
	overflow: hidden;
	border-radius: var(--bgl-card-radius, 12px);
}

.height-100-2 {
	height: calc(100vh - 2rem);
}

.max-height-100-2 {
	max-height: calc(100vh - 2rem);
}

.dialog-close {
	margin-top: 0.125rem;
}

.overlay-btn {
	opacity: 0;
	animation: fade-in 0.3s ease-out 0.1s forwards;
}

/* Backdrop animations */
dialog::backdrop {
	background: var(--bgl-dark-bg, rgba(0, 0, 0, 0.5));
	opacity: 0;
}

dialog[open]::backdrop {
	animation: fade-in 0.2s ease-out forwards;
}

dialog.is-closing::backdrop {
	animation: fade-out 0.15s ease-in forwards;
}

/* Dialog position animations */
dialog.dialog-center[open] {
	animation: scale-fade-in 0.2s ease-out;
}

dialog.dialog-center.is-closing {
	animation: scale-fade-out 0.15s ease-in forwards;
}

dialog.dialog-right[open] {
	animation: slide-in-right 0.25s ease-out;
}

dialog.dialog-right.is-closing {
	animation: slide-out-right 0.2s ease-in forwards;
}

dialog.dialog-left[open] {
	animation: slide-in-left 0.25s ease-out;
}

dialog.dialog-left.is-closing {
	animation: slide-out-left 0.2s ease-in forwards;
}

dialog.dialog-top[open] {
	animation: slide-in-top 0.25s ease-out;
}

dialog.dialog-top.is-closing {
	animation: slide-out-top 0.2s ease-in forwards;
}

dialog.dialog-bottom[open] {
	animation: slide-in-bottom 0.25s ease-out;
}

dialog.dialog-bottom.is-closing {
	animation: slide-out-bottom 0.2s ease-in forwards;
}

/* Keyframes - shared and reusable */
@keyframes fade-in {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

@keyframes fade-out {
	from {
		opacity: 1;
	}

	to {
		opacity: 0;
	}
}

@keyframes scale-fade-in {
	from {
		opacity: 0;
		transform: scale(0.95) translateY(10px);
	}

	to {
		opacity: 1;
		transform: scale(1) translateY(0);
	}
}

@keyframes scale-fade-out {
	from {
		opacity: 1;
		transform: scale(1) translateY(0);
	}

	to {
		opacity: 0;
		transform: scale(0.95) translateY(10px);
	}
}

@keyframes slide-in-right {
	from {
		opacity: 0;
		transform: translateX(100%);
	}

	to {
		opacity: 1;
		transform: translateX(0);
	}
}

@keyframes slide-out-right {
	from {
		opacity: 1;
		transform: translateX(0);
	}

	to {
		opacity: 0;
		transform: translateX(100%);
	}
}

@keyframes slide-in-left {
	from {
		opacity: 0;
		transform: translateX(-100%);
	}

	to {
		opacity: 1;
		transform: translateX(0);
	}
}

@keyframes slide-out-left {
	from {
		opacity: 1;
		transform: translateX(0);
	}

	to {
		opacity: 0;
		transform: translateX(-100%);
	}
}

@keyframes slide-in-top {
	from {
		opacity: 0;
		transform: translateY(-100%);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes slide-out-top {
	from {
		opacity: 1;
		transform: translateY(0);
	}

	to {
		opacity: 0;
		transform: translateY(-100%);
	}
}

@keyframes slide-in-bottom {
	from {
		opacity: 0;
		transform: translateY(100%);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes slide-out-bottom {
	from {
		opacity: 1;
		transform: translateY(0);
	}

	to {
		opacity: 0;
		transform: translateY(100%);
	}
}

/* Full width adjustments */
dialog[style*="--dialog-width: 100%"] {
	max-width: calc(100vw - 2rem);
}

dialog.dialog-left[style*="--dialog-width: 100%"],
dialog.dialog-right[style*="--dialog-width: 100%"] {
	max-width: calc(100vw - 2rem);
	width: calc(100vw - 2rem);
}

/* Mobile adjustments */
@media screen and (max-width: 910px) {

	dialog.dialog-left .grid-dialog,
	dialog.dialog-right .grid-dialog {
		max-height: 100vh;
	}

	dialog.dialog-left,
	dialog.dialog-right {
		width: 100%;
	}
}
</style>
<!-- prettier-ignore-end -->
<!-- eslint-enable -->
