<script setup lang="ts">
/**
 * Dialog - Native dialog wrapper with animations
 *
 * Uses native <dialog> element for:
 * - Automatic focus trap
 * - ESC key handling
 * - Backdrop via ::backdrop
 * - Browser-managed z-index stacking
 */
import type { DialogWidth, DialogPosition } from './dialogTypes'
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
}>(), {
	width: 'm',
	position: 'center',
	dismissable: true
})

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

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

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

const positionClass = computed(() => {
	if (props.position === 'left') return 'dialog-left'
	if (props.position === 'right') return 'dialog-right'
	return 'dialog-center'
})

// Handle open/close
watch(() => props.open, (isOpen) => {
	if (isOpen) {
		dialogRef.value?.showModal()
		isClosing.value = false
	} 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() {
	emit('update:open', false)
}

defineExpose({ close })
</script>

<template>
	<dialog
		ref="dialogRef" :class="[positionClass, { 'is-closing': isClosing }]"
		:style="{ '--dialog-width': widthStyle }" @click="onBackdropClick" @cancel="onCancel"
		@animationend="onAnimationEnd"
	>
		<div class="dialog-content" @click.stop>
			<!-- Header -->
			<header v-if="title || dismissable" class="dialog-header">
				<h2 v-if="title" class="dialog-title">
					{{ title }}
				</h2>
				<button v-if="dismissable" type="button" class="dialog-close" aria-label="Close" @click="close">
					<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
						<path d="M18 6L6 18M6 6l12 12" />
					</svg>
				</button>
			</header>

			<!-- Body -->
			<div class="dialog-body">
				<slot />
			</div>

			<!-- Footer -->
			<footer v-if="$slots.footer" class="dialog-footer">
				<slot name="footer" />
			</footer>
		</div>
	</dialog>
</template>

<style scoped>
dialog {
	border: none;
	border-radius: var(--bgl-card-radius, 12px);
	padding: 0;
	max-width: var(--dialog-width);
	width: calc(100% - 2rem);
	max-height: calc(100vh - 2rem);
	background: var(--bgl-popup-bg, #fff);
	color: var(--bgl-text, #1a1a1a);
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
	overflow: hidden;
}

dialog::backdrop {
	background: var(--bgl-dark-bg, rgba(0, 0, 0, 0.5));
	opacity: 0;
	transition: opacity 0.2s ease-out;
}

dialog[open]::backdrop {
	opacity: 1;
}

/* Center position (default) */
dialog.dialog-center {
	margin: auto;
}

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

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

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

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

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

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

/* Right position */
dialog.dialog-right {
	margin: 0;
	margin-inline-start: auto;
	margin-inline-end: 1rem;
	margin-top: 1rem;
	margin-bottom: 1rem;
	height: calc(100vh - 2rem);
	max-height: calc(100vh - 2rem);
	border-radius: var(--bgl-card-radius, 12px);
}

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

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

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

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

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

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

/* Left position */
dialog.dialog-left {
	margin: 0;
	margin-inline-end: auto;
	margin-inline-start: 1rem;
	margin-top: 1rem;
	margin-bottom: 1rem;
	height: calc(100vh - 2rem);
	max-height: calc(100vh - 2rem);
	border-radius: var(--bgl-card-radius, 12px);
}

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

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

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

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

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

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

/* Content structure */
.dialog-content {
	display: flex;
	flex-direction: column;
	height: 100%;
	max-height: inherit;
}

.dialog-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1rem 1.5rem;
	border-bottom: 1px solid var(--bgl-border-color, #e5e5e5);
	flex-shrink: 0;
}

.dialog-title {
	margin: 0;
	font-size: 1.125rem;
	font-weight: 600;
}

.dialog-close {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border: none;
	background: transparent;
	border-radius: 6px;
	cursor: pointer;
	color: var(--bgl-text-secondary, #666);
	transition: background 0.15s ease, color 0.15s ease;
}

.dialog-close:hover {
	background: var(--bgl-gray-tint, #f0f0f0);
	color: var(--bgl-text, #1a1a1a);
}

.dialog-body {
	flex: 1;
	padding: 1.5rem;
	overflow-y: auto;
}

.dialog-footer {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 0.75rem;
	padding: 1rem 1.5rem;
	border-top: 1px solid var(--bgl-border-color, #e5e5e5);
	flex-shrink: 0;
}

/* Full width */
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: 640px) {

	dialog.dialog-left,
	dialog.dialog-right {
		margin: 0;
		width: 100%;
		max-width: 100%;
		height: 100vh;
		max-height: 100vh;
		border-radius: 0;
	}
}
</style>
